/* This file is part of Ext JS 5.1.1.451 Copyright (c) 2011-2015 Sencha Inc Contact: http://www.sencha.com/contact GNU General Public License Usage This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact. Version: 5.1.1.451 Build date: 2015-05-06 21:53:32 (130b7b8a6334f33aee5c2952cefb768cadb3bf78) */ var Ext = Ext || {}; Ext.Boot = Ext.Boot || (function (emptyFn) { var doc = document, apply = function (dest, src, defaults) { if (defaults) { apply(dest, defaults); } if (dest && src && typeof src == 'object') { for (var key in src) { dest[key] = src[key]; } } return dest; }, _config = { disableCaching: (/[?&](?:cache|disableCacheBuster)\b/i.test(location.search) || !(/http[s]?\:/i.test(location.href)) || /(^|[ ;])ext-cache=1/.test(doc.cookie)) ? false : true, disableCachingParam: '_dc', loadDelay: false, preserveScripts: true, charset: undefined }, cssRe = /\.css(?:\?|$)/i, resolverEl = doc.createElement('a'), isBrowser = typeof window !== 'undefined', _environment = { browser: isBrowser, node: !isBrowser && (typeof require === 'function'), phantom: (typeof phantom !== 'undefined' && phantom.fs) }, _tags = (Ext.platformTags = {}), _debug = function (message) { }, _apply = function (object, config, defaults) { if (defaults) { _apply(object, defaults); } if (object && config && typeof config === 'object') { for (var i in config) { object[i] = config[i]; } } return object; }, Boot = { loading: 0, loaded: 0, env: _environment, config: _config, scripts: { }, currentFile: null, suspendedQueue: [], currentRequest: null, syncMode: false, debug: _debug, useElements: true, listeners: [], Request: Request, Entry: Entry, detectPlatformTags: function () { var ua = navigator.userAgent, isMobile = _tags.isMobile = /Mobile(\/|\s)/.test(ua), isPhone, isDesktop, isTablet, touchSupported, isIE10, isBlackberry, element = document.createElement('div'), uaTagChecks = [ 'iPhone', 'iPod', 'Android', 'Silk', 'Android 2', 'BlackBerry', 'BB', 'iPad', 'RIM Tablet OS', 'MSIE 10', 'Trident', 'Chrome', 'Tizen', 'Firefox', 'Safari', 'Windows Phone' ], isEventSupported = function(name, tag) { if (tag === undefined) { tag = window; } var eventName = 'on' + name.toLowerCase(), isSupported = (eventName in element); if (!isSupported) { if (element.setAttribute && element.removeAttribute) { element.setAttribute(eventName, ''); isSupported = typeof element[eventName] === 'function'; if (typeof element[eventName] !== 'undefined') { element[eventName] = undefined; } element.removeAttribute(eventName); } } return isSupported; }, uaTags = {}, len = uaTagChecks.length, check, c; for (c = 0; c < len; c++) { check = uaTagChecks[c]; uaTags[check] = new RegExp(check).test(ua); } isPhone = (uaTags.iPhone || uaTags.iPod) || (!uaTags.Silk && (uaTags.Android && (uaTags['Android 2'] || isMobile))) || ((uaTags.BlackBerry || uaTags.BB) && uaTags.isMobile) || (uaTags['Windows Phone']); isTablet = (!_tags.isPhone) && ( uaTags.iPad || uaTags.Android || uaTags.Silk || uaTags['RIM Tablet OS'] || (uaTags['MSIE 10'] && /; Touch/.test(ua)) ); touchSupported = isEventSupported('touchend') || navigator.maxTouchPoints || navigator.msMaxTouchPoints; isDesktop = !isPhone && !isTablet; isIE10 = uaTags['MSIE 10']; isBlackberry = uaTags.Blackberry || uaTags.BB; apply(_tags, Boot.loadPlatformsParam(), { phone: isPhone, tablet: isTablet, desktop: isDesktop, touch: touchSupported, ios: (uaTags.iPad || uaTags.iPhone || uaTags.iPod), android: uaTags.Android || uaTags.Silk, blackberry: isBlackberry, safari: uaTags.Safari && !isBlackberry, chrome: uaTags.Chrome, ie10: isIE10, windows: isIE10 || uaTags.Trident, tizen: uaTags.Tizen, firefox: uaTags.Firefox }); }, loadPlatformsParam: function () { var paramsString = window.location.search.substr(1), paramsArray = paramsString.split("&"), params = {}, i, platforms = {}, tmpArray, tmplen, platform, name, enabled; for (i = 0; i < paramsArray.length; i++) { tmpArray = paramsArray[i].split("="); params[tmpArray[0]] = tmpArray[1]; } if (params.platformTags) { tmpArray = params.platform.split(/\W/); for (tmplen = tmpArray.length, i = 0; i < tmplen; i++) { platform = tmpArray[i].split(":"); name = platform[0]; if (platform.length > 1) { enabled = platform[1]; if (enabled === 'false' || enabled === '0') { enabled = false; } else { enabled = true; } } platforms[name] = enabled; } } return platform; }, filterPlatform: function (platform) { platform = [].concat(platform); var len, p, tag; for (len = platform.length, p = 0; p < len; p++) { tag = platform[p]; if (_tags.hasOwnProperty(tag)) { return !!_tags[tag]; } } return false; }, init: function () { var scriptEls = doc.getElementsByTagName('script'), len = scriptEls.length, re = /\/ext(\-[a-z\-]+)?\.js$/, entry, script, src, state, baseUrl, key, n, origin; for (n = 0; n < len; n++) { src = (script = scriptEls[n]).src; if (!src) { continue; } state = script.readyState || null; if (!baseUrl) { if (re.test(src)) { Boot.hasReadyState = ("readyState" in script); Boot.hasAsync = ("async" in script) || !Boot.hasReadyState; baseUrl = src; } } if (!Boot.scripts[key = Boot.canonicalUrl(src)]) { _debug("creating entry " + key + " in Boot.init"); entry = new Entry({ key: key, url: src, done: state === null || state === 'loaded' || state === 'complete', el: script, prop: 'src' }); } } if (!baseUrl) { script = scriptEls[scriptEls.length - 1]; baseUrl = script.src; Boot.hasReadyState = ('readyState' in script); Boot.hasAsync = ("async" in script) || !Boot.hasReadyState; } Boot.baseUrl = baseUrl.substring(0, baseUrl.lastIndexOf('/') + 1); origin = window.location.origin || window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: ''); Boot.origin = origin; Boot.detectPlatformTags(); Ext.filterPlatform = Boot.filterPlatform; }, canonicalUrl: function (url) { resolverEl.href = url; var ret = resolverEl.href, dc = _config.disableCachingParam, pos = dc ? ret.indexOf(dc + '=') : -1, c, end; if (pos > 0 && ((c = ret.charAt(pos - 1)) === '?' || c === '&')) { end = ret.indexOf('&', pos); end = (end < 0) ? '' : ret.substring(end); if (end && c === '?') { ++pos; end = end.substring(1); } ret = ret.substring(0, pos - 1) + end; } return ret; }, getConfig: function (name) { return name ? Boot.config[name] : Boot.config; }, setConfig: function (name, value) { if (typeof name === 'string') { Boot.config[name] = value; } else { for (var s in name) { Boot.setConfig(s, name[s]); } } return Boot; }, getHead: function () { return Boot.docHead || (Boot.docHead = doc.head || doc.getElementsByTagName('head')[0]); }, create: function (url, key, cfg) { var config = cfg || {}; config.url = url; config.key = key; return Boot.scripts[key] = new Entry(config); }, getEntry: function (url, cfg) { var key = Boot.canonicalUrl(url), entry = Boot.scripts[key]; if (!entry) { entry = Boot.create(url, key, cfg); } return entry; }, processRequest: function(request, sync) { request.loadEntries(sync); }, load: function (request) { _debug("Boot.load called"); var request = new Request(request); if (request.sync || Boot.syncMode) { return Boot.loadSync(request); } if (Boot.currentRequest) { _debug("current active request, suspending this request"); request.getEntries(); Boot.suspendedQueue.push(request); } else { Boot.currentRequest = request; Boot.processRequest(request, false); } return Boot; }, loadSync: function (request) { _debug("Boot.loadSync called"); var request = new Request(request); Boot.syncMode++; Boot.processRequest(request, true); Boot.syncMode--; return Boot; }, loadBasePrefix: function(request) { request = new Request(request); request.prependBaseUrl = true; return Boot.load(request); }, loadSyncBasePrefix: function(request) { request = new Request(request); request.prependBaseUrl = true; return Boot.loadSync(request); }, requestComplete: function(request) { var next; if (Boot.currentRequest === request) { Boot.currentRequest = null; while(Boot.suspendedQueue.length > 0) { next = Boot.suspendedQueue.shift(); if(!next.done) { _debug("resuming suspended request"); Boot.load(next); break; } } } if (!Boot.currentRequest && Boot.suspendedQueue.length == 0) { Boot.fireListeners(); } }, isLoading: function () { return !Boot.currentRequest && Boot.suspendedQueue.length == 0; }, fireListeners: function () { var listener; while (Boot.isLoading() && (listener = Boot.listeners.shift())) { listener(); } }, onBootReady: function (listener) { if (!Boot.isLoading()) { listener(); } else { Boot.listeners.push(listener); } }, getPathsFromIndexes: function (indexMap, loadOrder) { return Request.prototype.getPathsFromIndexes(indexMap, loadOrder); }, createLoadOrderMap: function(loadOrder) { return Request.prototype.createLoadOrderMap(loadOrder); }, fetch: function(url, complete, scope, async) { async = (async === undefined) ? !!complete : async; var xhr = new XMLHttpRequest(), result, status, content, exception = false, readyStateChange = function () { if (xhr && xhr.readyState == 4) { status = (xhr.status === 1223) ? 204 : (xhr.status === 0 && ((self.location || {}).protocol === 'file:' || (self.location || {}).protocol === 'ionp:')) ? 200 : xhr.status; content = xhr.responseText; result = { content: content, status: status, exception: exception }; if (complete) { complete.call(scope, result); } xhr = null; } }; if (async) { xhr.onreadystatechange = readyStateChange; } try { _debug("fetching " + url + " " + (async ? "async" : "sync")); xhr.open('GET', url, async); xhr.send(null); } catch (err) { exception = err; readyStateChange(); return result; } if (!async) { readyStateChange(); } return result; }, notifyAll: function(entry) { entry.notifyRequests(); } }; function Request(cfg) { if(cfg.$isRequest) { return cfg; } var cfg = cfg.url ? cfg : {url: cfg}, url = cfg.url, urls = url.charAt ? [ url ] : url, charset = cfg.charset || Boot.config.charset; _apply(cfg, { urls: urls, charset: charset }); _apply(this, cfg); }; Request.prototype = { $isRequest: true, createLoadOrderMap: function (loadOrder) { var len = loadOrder.length, loadOrderMap = {}, i, element; for (i = 0; i < len; i++) { element = loadOrder[i]; loadOrderMap[element.path] = element; } return loadOrderMap; }, getLoadIndexes: function (index, indexMap, loadOrder, includeUses, skipLoaded) { var item = loadOrder[index], len, i, reqs, entry, stop, added, idx, ridx, url; if (indexMap[index]) { return indexMap; } indexMap[index] = true; stop = false; while (!stop) { added = false; for (idx in indexMap) { if (indexMap.hasOwnProperty(idx)) { item = loadOrder[idx]; if (!item) { continue; } url = this.prepareUrl(item.path); entry = Boot.getEntry(url); if (!skipLoaded || !entry || !entry.done) { reqs = item.requires; if (includeUses && item.uses) { reqs = reqs.concat(item.uses); } for (len = reqs.length, i = 0; i < len; i++) { ridx = reqs[i]; if (!indexMap[ridx]) { indexMap[ridx] = true; added = true; } } } } } if (!added) { stop = true; } } return indexMap; }, getPathsFromIndexes: function (indexMap, loadOrder) { var indexes = [], paths = [], index, len, i; for (index in indexMap) { if (indexMap.hasOwnProperty(index) && indexMap[index]) { indexes.push(index); } } indexes.sort(function (a, b) { return a - b; }); for (len = indexes.length, i = 0; i < len; i++) { paths.push(loadOrder[indexes[i]].path); } return paths; }, expandUrl: function (url, indexMap, includeUses, skipLoaded) { if (typeof url == 'string') { url = [url]; } var me = this, loadOrder = me.loadOrder, loadOrderMap = me.loadOrderMap; if (loadOrder) { loadOrderMap = loadOrderMap || me.createLoadOrderMap(loadOrder); me.loadOrderMap = loadOrderMap; indexMap = indexMap || {}; var len = url.length, unmapped = [], i, item; for (i = 0; i < len; i++) { item = loadOrderMap[url[i]]; if (item) { me.getLoadIndexes(item.idx, indexMap, loadOrder, includeUses, skipLoaded); } else { unmapped.push(url[i]); } } return me.getPathsFromIndexes(indexMap, loadOrder).concat(unmapped); } return url; }, expandUrls: function (urls, includeUses) { if (typeof urls == "string") { urls = [urls]; } var expanded = [], expandMap = {}, tmpExpanded, len = urls.length, i, t, tlen, tUrl; for (i = 0; i < len; i++) { tmpExpanded = this.expandUrl(urls[i], {}, includeUses, true); for (t = 0, tlen = tmpExpanded.length; t < tlen; t++) { tUrl = tmpExpanded[t]; if (!expandMap[tUrl]) { expandMap[tUrl] = true; expanded.push(tUrl); } } } if (expanded.length == 0) { expanded = urls; } return expanded; }, expandLoadOrder: function () { var me = this, urls = me.urls, expanded; if (!me.expanded) { expanded = this.expandUrls(urls, true); me.expanded = true; } else { expanded = urls; } me.urls = expanded; if (urls.length != expanded.length) { me.sequential = true; } return me; }, getUrls: function () { this.expandLoadOrder(); return this.urls; }, prepareUrl: function(url) { if(this.prependBaseUrl) { return Boot.baseUrl + url; } return url; }, getEntries: function () { var me = this, entries = me.entries, i, entry, urls, url; if (!entries) { entries = []; urls = me.getUrls(); for (i = 0; i < urls.length; i++) { url = me.prepareUrl(urls[i]); entry = Boot.getEntry(url, { buster: me.buster, charset: me.charset }); entry.requests.push(me); entries.push(entry); } me.entries = entries; } return entries; }, loadEntries: function(sync) { var me = this, entries = me.getEntries(), len = entries.length, start = me.loadStart || 0, continueLoad, entry, i; if(sync !== undefined) { me.sync = sync; } me.loaded = me.loaded || 0; me.loading = me.loading || len; for(i = start; i < len; i++) { entry = entries[i]; if(!entry.loaded) { continueLoad = entries[i].load(me.sync); } else { continueLoad = true; } if(!continueLoad) { me.loadStart = i; entry.onDone(function(){ me.loadEntries(sync); }); break; } } me.processLoadedEntries(); }, processLoadedEntries: function () { var me = this, entries = me.getEntries(), len = entries.length, start = me.startIndex || 0, i, entry; if (!me.done) { for (i = start; i < len; i++) { entry = entries[i]; if (!entry.loaded) { me.startIndex = i; return; } if (!entry.evaluated) { entry.evaluate(); } if (entry.error) { me.error = true; } } me.notify(); } }, notify: function () { var me = this; if (!me.done) { var error = me.error, fn = me[error ? 'failure' : 'success'], delay = ('delay' in me) ? me.delay : (error ? 1 : Boot.config.chainDelay), scope = me.scope || me; me.done = true; if (fn) { if (delay === 0 || delay > 0) { setTimeout(function () { fn.call(scope, me); }, delay); } else { fn.call(scope, me); } } me.fireListeners(); Boot.requestComplete(me); } }, onDone: function(listener) { var me = this, listeners = me.listeners || (me.listeners = []); if(me.done) { listener(me); } else { listeners.push(listener); } }, fireListeners: function() { var listeners = this.listeners, listener; if(listeners) { _debug("firing request listeners"); while((listener = listeners.shift())) { listener(this); } } } }; function Entry(cfg) { if(cfg.$isEntry) { return cfg; } _debug("creating entry for " + cfg.url); var charset = cfg.charset || Boot.config.charset, manifest = Ext.manifest, loader = manifest && manifest.loader, cache = (cfg.cache !== undefined) ? cfg.cache : (loader && loader.cache), buster, busterParam; if(cache === undefined) { cache = !Boot.config.disableCaching; } if(cache === false) { buster = +new Date(); } else if(cache !== true) { buster = cache; } if(buster) { busterParam = (loader && loader.cacheParam) || Boot.config.disableCachingParam; buster = busterParam + "=" + buster; }; _apply(cfg, { charset: charset, buster: buster, requests: [] }); _apply(this, cfg); }; Entry.prototype = { $isEntry: true, done: false, evaluated: false, loaded: false, isCrossDomain: function() { var me = this; if(me.crossDomain === undefined) { _debug("checking " + me.getLoadUrl() + " for prefix " + Boot.origin); me.crossDomain = (me.getLoadUrl().indexOf(Boot.origin) !== 0); } return me.crossDomain; }, isCss: function () { var me = this; if (me.css === undefined) { me.css = me.url && cssRe.test(me.url); } return this.css; }, getElement: function (tag) { var me = this, el = me.el; if (!el) { _debug("creating element for " + me.url); if (me.isCss()) { tag = tag || "link"; el = doc.createElement(tag); if(tag == "link") { el.rel = 'stylesheet'; me.prop = 'href'; } else { me.prop="textContent"; } el.type = "text/css"; } else { tag = tag || "script"; el = doc.createElement(tag); el.type = 'text/javascript'; me.prop = 'src'; if (Boot.hasAsync) { el.async = false; } } me.el = el; } return el; }, getLoadUrl: function () { var me = this, url = Boot.canonicalUrl(me.url); if (!me.loadUrl) { me.loadUrl = !!me.buster ? (url + (url.indexOf('?') === -1 ? '?' : '&') + me.buster) : url; } return me.loadUrl; }, fetch: function (req) { var url = this.getLoadUrl(), async = !!req.async, complete = req.complete; Boot.fetch(url, complete, this, async); }, onContentLoaded: function (response) { var me = this, status = response.status, content = response.content, exception = response.exception, url = this.getLoadUrl(); me.loaded = true; if ((exception || status === 0) && !_environment.phantom) { me.error = ("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 where cross " + "origin requests are not allowed for security reasons. Try " + "asynchronous loading instead.") || true; me.evaluated = true; } else if ((status >= 200 && status < 300) || status === 304 || _environment.phantom || (status === 0 && content.length > 0) ) { me.content = content; } else { me.error = ("Failed loading synchronously via XHR: '" + url + "'. Please verify that the file exists. XHR status code: " + status) || true; me.evaluated = true; } }, createLoadElement: function(callback) { var me = this, el = me.getElement(), readyStateChange = function(){ if (this.readyState === 'loaded' || this.readyState === 'complete') { if(callback) { callback(); } } }, errorFn = function() { me.error = true; if(callback) { callback(); } }; me.preserve = true; el.onerror = errorFn; if(Boot.hasReadyState) { el.onreadystatechange = readyStateChange; } else { el.onload = callback; } el[me.prop] = me.getLoadUrl(); }, onLoadElementReady: function() { Boot.getHead().appendChild(this.getElement()); this.evaluated = true; }, inject: function (content, asset) { _debug("injecting content for " + this.url); var me = this, head = Boot.getHead(), url = me.url, key = me.key, base, el, ieMode, basePath; if (me.isCss()) { me.preserve = true; basePath = key.substring(0, key.lastIndexOf("/") + 1); base = doc.createElement('base'); base.href = basePath; if(head.firstChild) { head.insertBefore(base, head.firstChild); } else { head.appendChild(base); } base.href = base.href; if (url) { content += "\n/*# sourceURL=" + key + " */"; } el = me.getElement("style"); ieMode = ('styleSheet' in el); head.appendChild(base); if(ieMode) { head.appendChild(el); el.styleSheet.cssText = content; } else { el.textContent = content; head.appendChild(el); } head.removeChild(base); } else { if (url) { content += "\n//# sourceURL=" + key; } Ext.globalEval(content); } return me; }, loadCrossDomain: function() { var me = this, complete = function(){ me.loaded = me.evaluated = me.done = true; me.notifyRequests(); }; if(me.isCss()) { me.createLoadElement(); me.evaluateLoadElement(); complete(); } else { me.createLoadElement(function(){ complete(); }); me.evaluateLoadElement(); return false; } return true; }, loadElement: function() { var me = this, complete = function(){ me.loaded = me.evaluated = me.done = true; me.notifyRequests(); }; if(me.isCss()) { return me.loadCrossDomain(); } else { me.createLoadElement(function(){ complete(); }); me.evaluateLoadElement(); } return true; }, loadSync: function() { var me = this; me.fetch({ async: false, complete: function (response) { me.onContentLoaded(response); } }); me.evaluate(); me.notifyRequests(); }, load: function (sync) { var me = this; if (!me.loaded) { if(me.loading) { return false; } me.loading = true; if (!sync) { if(me.isCrossDomain()) { return me.loadCrossDomain(); } else if(!me.isCss() && Boot.hasReadyState) { me.createLoadElement(function () { me.loaded = true; me.notifyRequests(); }); } else if(Boot.useElements) { return me.loadElement(); } else { me.fetch({ async: !sync, complete: function (response) { me.onContentLoaded(response); me.notifyRequests(); } }); } } else { me.loadSync(); } } return true; }, evaluateContent: function () { this.inject(this.content); this.content = null; }, evaluateLoadElement: function() { Boot.getHead().appendChild(this.getElement()); }, evaluate: function () { var me = this; if(!me.evaluated) { if(me.evaluating) { return; } me.evaluating = true; if(me.content !== undefined) { me.evaluateContent(); } else if(!me.error) { me.evaluateLoadElement(); } me.evaluated = me.done = true; me.cleanup(); } }, cleanup: function () { var me = this, el = me.el, prop; if (!el) { return; } if (!me.preserve) { me.el = null; el.parentNode.removeChild(el); for (prop in el) { try { if (prop !== me.prop) { el[prop] = null; } delete el[prop]; } catch (cleanEx) { } } } el.onload = el.onerror = el.onreadystatechange = emptyFn; }, notifyRequests: function () { var requests = this.requests, len = requests.length, i, request; for (i = 0; i < len; i++) { request = requests[i]; request.processLoadedEntries(); } if(this.done) { this.fireListeners(); } }, onDone: function(listener) { var me = this, listeners = me.listeners || (me.listeners = []); if(me.done) { listener(me); } else { listeners.push(listener); } }, fireListeners: function() { var listeners = this.listeners, listener; if(listeners && listeners.length > 0) { _debug("firing event listeners for url " + this.url); while((listener = listeners.shift())) { listener(this); } } } }; Ext.disableCacheBuster = function (disable, path) { var date = new Date(); date.setTime(date.getTime() + (disable ? 10 * 365 : -1) * 24 * 60 * 60 * 1000); date = date.toGMTString(); doc.cookie = 'ext-cache=1; expires=' + date + '; path=' + (path || '/'); }; if (_environment.node) { Boot.prototype.load = Boot.prototype.loadSync = function (request) { require(filePath); onLoad.call(scope); }; Boot.prototype.init = emptyFn; } Boot.init(); return Boot; }(function () { })); Ext.globalEval = Ext.globalEval || (this.execScript ? function (code) { execScript(code); } : function ($$code) { eval.call(window, $$code); }); if (!Function.prototype.bind) { (function () { var slice = Array.prototype.slice, bind = function (me) { var args = slice.call(arguments, 1), method = this; if (args.length) { return function () { var t = arguments; return method.apply(me, t.length ? args.concat(slice.call(t)) : args); }; } args = null; return function () { return method.apply(me, arguments); }; }; Function.prototype.bind = bind; bind.$extjs = true; }()); } var Ext = Ext || {}; Ext._startTime = Date.now ? Date.now() : (+new Date()); (function() { var global = this, objectPrototype = Object.prototype, toString = objectPrototype.toString, enumerables = [ 'valueOf', 'toLocaleString', 'toString', 'constructor' ], emptyFn = function() {}, privateFn = function() {}, identityFn = function(o) { return o; }, callOverrideParent = function() { var method = callOverrideParent.caller.caller; return method.$owner.prototype[method.$name].apply(this, arguments); }, manifest = Ext.manifest || {}, i, iterableRe = /\[object\s*(?:Array|Arguments|\w*Collection|\w*List|HTML\s+document\.all\s+class)\]/, MSDateRe = /^\\?\/Date\(([-+])?(\d+)(?:[+-]\d{4})?\)\\?\/$/; Ext.global = global; emptyFn.$nullFn = identityFn.$nullFn = emptyFn.$emptyFn = identityFn.$identityFn = privateFn.$nullFn = true; privateFn.$privacy = 'framework'; Ext['suspendLayouts'] = Ext['resumeLayouts'] = emptyFn; for (i in { toString: 1 }) { enumerables = null; } Ext.enumerables = enumerables; Ext.apply = function(object, config, defaults) { if (defaults) { Ext.apply(object, defaults); } 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]; } } } } return object; }; Ext.buildSettings = Ext.apply({ baseCSSPrefix: 'x-' }, Ext.buildSettings || {}); Ext.apply(Ext, { idSeed: 0, idPrefix: 'ext-', isSecure: /^https/i.test(window.location.protocol), enableGarbageCollector: false, enableListenerCollection: true, name: Ext.sandboxName || 'Ext', privateFn: privateFn, emptyFn: emptyFn, identityFn: identityFn, frameStartTime: +new Date(), manifest: manifest, debugConfig: Ext.debugConfig || manifest.debug || { hooks: { '*': true } }, validIdRe: /^[a-z_][a-z0-9\-_]*$/i, BLANK_IMAGE_URL: 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', makeIdSelector: function(id) { if (!Ext.validIdRe.test(id)) { Ext.Error.raise('Invalid id selector: "' + id + '"'); } return '#' + id; }, id: function(o, prefix) { if (o && o.id) { return o.id; } var id = (prefix || Ext.idPrefix) + (++Ext.idSeed); if (o) { o.id = id; } return id; }, returnId: function(o) { return o.getId(); }, returnTrue: function() { return true; }, emptyString: new String(), baseCSSPrefix: Ext.buildSettings.baseCSSPrefix, $eventNameMap: {}, $vendorEventRe: /^(Moz.+|MS.+|webkit.+)/, canonicalEventName: function(name) { return Ext.$eventNameMap[name] || (Ext.$eventNameMap[name] = (Ext.$vendorEventRe.test(name) ? name : name.toLowerCase())); }, applyIf: function(object, config) { var property; if (object) { for (property in config) { if (object[property] === undefined) { object[property] = config[property]; } } } return object; }, now: (global.performance && global.performance.now) ? function() { return performance.now(); } : (Date.now || (Date.now = function() { return +new Date(); })), 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(); } } } return null; }, destroyMembers: function(object) { for (var ref, name, i = 1, a = arguments, len = a.length; i < len; i++) { ref = object[name = a[i]]; if (ref != null) { object[name] = Ext.destroy(ref); } } }, override: function(target, overrides) { if (target.$isClass) { target.override(overrides); } else if (typeof target === 'function') { Ext.apply(target.prototype, overrides); } else { var owner = target.self, name, value; if (owner && owner.$isClass) { for (name in overrides) { if (overrides.hasOwnProperty(name)) { value = overrides[name]; if (typeof value === 'function') { if (owner.$className) { value.name = owner.$className + '#' + name; } value.$name = name; value.$owner = owner; value.$previous = target.hasOwnProperty(name) ? target[name] : callOverrideParent; } target[name] = value; } } } else { Ext.apply(target, overrides); } } return target; }, valueFrom: function(value, defaultValue, allowBlank) { return Ext.isEmpty(value, allowBlank) ? defaultValue : value; }, isEmpty: function(value, allowEmptyString) { return (value == null) || (!allowEmptyString ? value === '' : false) || (Ext.isArray(value) && value.length === 0); }, isArray: ('isArray' in Array) ? Array.isArray : function(value) { return toString.call(value) === '[object Array]'; }, isDate: function(value) { return toString.call(value) === '[object Date]'; }, isMSDate: function(value) { if (!Ext.isString(value)) { return false; } return MSDateRe.test(value); }, isObject: (toString.call(null) === '[object Object]') ? function(value) { return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.ownerDocument === undefined; } : function(value) { return toString.call(value) === '[object Object]'; }, isSimpleObject: function(value) { return value instanceof Object && value.constructor === Object; }, isPrimitive: function(value) { var type = typeof value; return type === 'string' || type === 'number' || type === 'boolean'; }, isFunction: (typeof document !== 'undefined' && typeof document.getElementsByTagName('body') === 'function') ? function(value) { return !!value && toString.call(value) === '[object Function]'; } : function(value) { return !!value && typeof value === 'function'; }, isNumber: function(value) { return typeof value === 'number' && isFinite(value); }, isNumeric: function(value) { return !isNaN(parseFloat(value)) && isFinite(value); }, isString: function(value) { return typeof value === 'string'; }, isBoolean: function(value) { return typeof value === 'boolean'; }, isElement: function(value) { return value ? value.nodeType === 1 : false; }, isTextNode: function(value) { return value ? value.nodeName === "#text" : false; }, isDefined: function(value) { return typeof value !== 'undefined'; }, isIterable: function(value) { if (!value || typeof value.length !== 'number' || typeof value === 'string' || Ext.isFunction(value)) { return false; } if (!value.propertyIsEnumerable) { return !!value.item; } if (value.hasOwnProperty('length') && !value.propertyIsEnumerable('length')) { return true; } return iterableRe.test(toString.call(value)); }, isDebugEnabled: function(className, defaultEnabled) { var debugConfig = Ext.debugConfig.hooks; if (debugConfig.hasOwnProperty(className)) { return debugConfig[className]; } var enabled = debugConfig['*'], prefixLength = 0; if (defaultEnabled !== undefined) { enabled = defaultEnabled; } if (!className) { return enabled; } for (var prefix in debugConfig) { var value = debugConfig[prefix]; if (className.charAt(prefix.length) === '.') { if (className.substring(0, prefix.length) === prefix) { if (prefixLength < prefix.length) { prefixLength = prefix.length; enabled = value; } } } } return enabled; } || emptyFn, clone: function(item) { if (item === null || item === undefined) { return item; } if (item.nodeType && item.cloneNode) { return item.cloneNode(true); } var type = toString.call(item), i, j, k, clone, key; if (type === '[object Date]') { return new Date(item.getTime()); } if (type === '[object Array]') { i = item.length; clone = []; while (i--) { clone[i] = Ext.clone(item[i]); } } else if (type === '[object Object]' && item.constructor === Object) { clone = {}; for (key in item) { clone[key] = Ext.clone(item[key]); } if (enumerables) { for (j = enumerables.length; j--; ) { k = enumerables[j]; if (item.hasOwnProperty(k)) { clone[k] = item[k]; } } } } return clone || item; }, getUniqueGlobalNamespace: function() { var uniqueGlobalNamespace = this.uniqueGlobalNamespace, i; if (uniqueGlobalNamespace === undefined) { i = 0; do { uniqueGlobalNamespace = 'ExtBox' + (++i); } while (global[uniqueGlobalNamespace] !== undefined); global[uniqueGlobalNamespace] = Ext; this.uniqueGlobalNamespace = uniqueGlobalNamespace; } return uniqueGlobalNamespace; }, functionFactoryCache: {}, cacheableFunctionFactory: function() { var me = this, args = Array.prototype.slice.call(arguments), cache = me.functionFactoryCache, idx, fn, ln; if (Ext.isSandboxed) { ln = args.length; if (ln > 0) { ln--; args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln]; } } idx = args.join(''); fn = cache[idx]; if (!fn) { fn = Function.prototype.constructor.apply(Function.prototype, args); cache[idx] = fn; } return fn; }, functionFactory: function() { var args = Array.prototype.slice.call(arguments), ln; if (Ext.isSandboxed) { ln = args.length; if (ln > 0) { ln--; args[ln] = 'var Ext=window.' + Ext.name + ';' + args[ln]; } } return Function.prototype.constructor.apply(Function.prototype, args); }, Logger: { log: function(message, priority) { if (message && global.console) { if (!priority || !(priority in global.console)) { priority = 'log'; } message = '[' + priority.toUpperCase() + '] ' + message; global.console[priority](message); } }, verbose: function(message) { this.log(message, 'verbose'); }, info: function(message) { this.log(message, 'info'); }, warn: function(message) { this.log(message, 'warn'); }, error: function(message) { throw new Error(message); }, deprecate: function(message) { this.log(message, 'warn'); } } || { verbose: emptyFn, log: emptyFn, info: emptyFn, warn: emptyFn, error: function(message) { throw new Error(message); }, deprecate: emptyFn }, getElementById: function(id) { return document.getElementById(id); }, splitAndUnescape: (function() { var cache = {}; return function(origin, delimiter) { if (!origin) { return []; } else if (!delimiter) { return [ origin ]; } var replaceRe = cache[delimiter] || (cache[delimiter] = new RegExp('\\\\' + delimiter, 'g')), result = [], parts, part; parts = origin.split(delimiter); while ((part = parts.shift()) !== undefined) { while (part.charAt(part.length - 1) === '\\' && parts.length > 0) { part = part + delimiter + parts.shift(); } part = part.replace(replaceRe, delimiter); result.push(part); } return result; }; })() }); Ext.returnTrue.$nullFn = Ext.returnId.$nullFn = true; }()); (function() { function toString() { var me = this, cls = me.sourceClass, method = me.sourceMethod, msg = me.msg; if (method) { if (msg) { method += '(): '; method += msg; } else { method += '()'; } } if (cls) { method = method ? (cls + '.' + method) : cls; } return method || msg || ''; } Ext.Error = function(config) { if (Ext.isString(config)) { config = { msg: config }; } var error = new Error(); Ext.apply(error, config); error.message = error.message || error.msg; error.toString = toString; return error; }; Ext.apply(Ext.Error, { ignore: false, raise: function(err) { err = err || {}; if (Ext.isString(err)) { err = { msg: err }; } var me = this, method = me.raise.caller, msg, name; if (method) { if (!err.sourceMethod && (name = method.$name)) { err.sourceMethod = name; } if (!err.sourceClass && (name = method.$owner) && (name = name.$className)) { err.sourceClass = name; } } if (me.handle(err) !== true) { msg = toString.call(err); Ext.log({ msg: msg, level: 'error', dump: err, stack: true }); throw new Ext.Error(err); } }, handle: function() { return this.ignore; } }); })(); Ext.deprecated = function(suggestion) { if (!suggestion) { suggestion = ''; } function fail() { Ext.Error.raise('The method "' + fail.$owner.$className + '.' + fail.$name + '" has been removed. ' + suggestion); } return fail; return Ext.emptyFn; }; (function() { if (typeof window === 'undefined') { return; } var last = 0, notify = function() { var cnt = Ext.log && Ext.log.counters, n = cnt && (cnt.error + cnt.warn + cnt.info + cnt.log), msg; if (n && last !== n) { msg = []; if (cnt.error) { msg.push('Errors: ' + cnt.error); } if (cnt.warn) { msg.push('Warnings: ' + cnt.warn); } if (cnt.info) { msg.push('Info: ' + cnt.info); } if (cnt.log) { msg.push('Log: ' + cnt.log); } window.status = '*** ' + msg.join(' -- '); last = n; } }; setInterval(notify, 1000); }()); Ext.Array = (function() { var arrayPrototype = Array.prototype, slice = arrayPrototype.slice, supportsSplice = (function() { var array = [], lengthBefore, j = 20; if (!array.splice) { return false; } while (j--) { array.push("A"); } array.splice(15, 0, "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F"); lengthBefore = array.length; array.splice(13, 0, "XXX"); if (lengthBefore + 1 !== array.length) { return false; } return true; }()), supportsIndexOf = 'indexOf' in arrayPrototype, supportsSliceOnNodeList = true; function stableSort(array, userComparator) { var len = array.length, indices = new Array(len), i; for (i = 0; i < len; i++) { indices[i] = i; } indices.sort(function(index1, index2) { return userComparator(array[index1], array[index2]) || (index1 - index2); }); for (i = 0; i < len; i++) { indices[i] = array[indices[i]]; } for (i = 0; i < len; i++) { array[i] = indices[i]; } return array; } try { if (typeof document !== 'undefined') { slice.call(document.getElementsByTagName('body')); } } catch (e) { supportsSliceOnNodeList = false; } var fixArrayIndex = function(array, index) { return (index < 0) ? Math.max(0, array.length + index) : Math.min(array.length, index); }, replaceSim = function(array, index, removeCount, insert) { var add = insert ? insert.length : 0, length = array.length, pos = fixArrayIndex(array, index); if (pos === length) { if (add) { array.push.apply(array, insert); } } else { var remove = Math.min(removeCount, length - pos), tailOldPos = pos + remove, tailNewPos = tailOldPos + add - remove, tailCount = length - tailOldPos, lengthAfterRemove = length - remove, i; if (tailNewPos < tailOldPos) { for (i = 0; i < tailCount; ++i) { array[tailNewPos + i] = array[tailOldPos + i]; } } else if (tailNewPos > tailOldPos) { for (i = tailCount; i--; ) { array[tailNewPos + i] = array[tailOldPos + i]; } } if (add && pos === lengthAfterRemove) { array.length = lengthAfterRemove; array.push.apply(array, insert); } else { array.length = lengthAfterRemove + add; for (i = 0; i < add; ++i) { array[pos + i] = insert[i]; } } } return array; }, replaceNative = function(array, index, removeCount, insert) { if (insert && insert.length) { if (index === 0 && !removeCount) { array.unshift.apply(array, insert); } else if (index < array.length) { array.splice.apply(array, [ index, removeCount ].concat(insert)); } else { array.push.apply(array, insert); } } else { array.splice(index, removeCount); } return array; }, eraseSim = function(array, index, removeCount) { return replaceSim(array, index, removeCount); }, eraseNative = function(array, index, removeCount) { array.splice(index, removeCount); return array; }, spliceSim = function(array, index, removeCount) { var pos = fixArrayIndex(array, index), removed = array.slice(index, fixArrayIndex(array, pos + removeCount)); if (arguments.length < 4) { replaceSim(array, pos, removeCount); } else { replaceSim(array, pos, removeCount, slice.call(arguments, 3)); } return removed; }, spliceNative = function(array) { return array.splice.apply(array, slice.call(arguments, 1)); }, erase = supportsSplice ? eraseNative : eraseSim, replace = supportsSplice ? replaceNative : replaceSim, splice = supportsSplice ? spliceNative : spliceSim, ExtArray = { binarySearch: function(array, item, begin, end, compareFn) { var length = array.length, middle, comparison; if (begin instanceof Function) { compareFn = begin; begin = 0; end = length; } else if (end instanceof Function) { compareFn = end; end = length; } else { if (begin === undefined) { begin = 0; } if (end === undefined) { end = length; } compareFn = compareFn || ExtArray.lexicalCompare; } --end; while (begin <= end) { middle = (begin + end) >> 1; comparison = compareFn(item, array[middle]); if (comparison >= 0) { begin = middle + 1; } else if (comparison < 0) { end = middle - 1; } } return begin; }, defaultCompare: function(lhs, rhs) { return (lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0); }, lexicalCompare: function(lhs, rhs) { lhs = String(lhs); rhs = String(rhs); return (lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0); }, 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 { for (i = ln - 1; i > -1; i--) { if (fn.call(scope || array[i], array[i], i, array) === false) { return i; } } } return true; }, forEach: ('forEach' in arrayPrototype) ? function(array, fn, scope) { return array.forEach(fn, scope); } : function(array, fn, scope) { for (var i = 0, ln = array.length; i < ln; i++) { fn.call(scope, array[i], i, array); } }, indexOf: supportsIndexOf ? function(array, item, from) { return arrayPrototype.indexOf.call(array, item, from); } : function(array, item, from) { 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; } } return -1; }, contains: supportsIndexOf ? function(array, item) { return arrayPrototype.indexOf.call(array, item) !== -1; } : function(array, item) { var i, ln; for (i = 0 , ln = array.length; i < ln; i++) { if (array[i] === item) { return true; } } return false; }, toArray: function(iterable, start, end) { if (!iterable || !iterable.length) { return []; } if (typeof iterable === 'string') { iterable = iterable.split(''); } if (supportsSliceOnNodeList) { return slice.call(iterable, start || 0, end || iterable.length); } 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 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]); } return ret; }, map: ('map' in arrayPrototype) ? function(array, fn, scope) { Ext.Assert.isFunction(fn, 'Ext.Array.map must have a callback function passed as second argument.'); return array.map(fn, scope); } : function(array, fn, scope) { Ext.Assert.isFunction(fn, 'Ext.Array.map must have a callback function passed as second argument.'); var results = [], i = 0, len = array.length; for (; i < len; i++) { results[i] = fn.call(scope, array[i], i, array); } return results; }, every: ('every' in arrayPrototype) ? function(array, fn, scope) { Ext.Assert.isFunction(fn, 'Ext.Array.every must have a callback function passed as second argument.'); return array.every(fn, scope); } : function(array, fn, scope) { Ext.Assert.isFunction(fn, 'Ext.Array.every must have a callback function passed as second argument.'); var i = 0, ln = array.length; for (; i < ln; ++i) { if (!fn.call(scope, array[i], i, array)) { return false; } } return true; }, some: ('some' in arrayPrototype) ? function(array, fn, scope) { Ext.Assert.isFunction(fn, 'Ext.Array.some must have a callback function passed as second argument.'); return array.some(fn, scope); } : function(array, fn, scope) { Ext.Assert.isFunction(fn, 'Ext.Array.some must have a callback function passed as second argument.'); var i = 0, ln = array.length; for (; i < ln; ++i) { if (fn.call(scope, array[i], i, array)) { return true; } } return false; }, equals: function(array1, array2) { var len1 = array1.length, len2 = array2.length, i; if (array1 === array2) { return true; } if (len1 !== len2) { return false; } for (i = 0; i < len1; ++i) { if (array1[i] !== array2[i]) { return false; } } return true; }, 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); } } 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); } } return clone; }, filter: ('filter' in arrayPrototype) ? function(array, fn, scope) { Ext.Assert.isFunction(fn, 'Ext.Array.filter must have a filter function passed as second argument.'); return array.filter(fn, scope); } : function(array, fn, scope) { Ext.Assert.isFunction(fn, 'Ext.Array.filter must have a filter function passed as second argument.'); var results = [], i = 0, ln = array.length; for (; i < ln; i++) { if (fn.call(scope, array[i], i, array)) { results.push(array[i]); } } return results; }, findBy: function(array, fn, scope) { var i = 0, len = array.length; for (; i < len; i++) { if (fn.call(scope || array, array[i], i)) { return array[i]; } } return null; }, from: function(value, newReference) { if (value === undefined || value === null) { return []; } if (Ext.isArray(value)) { return (newReference) ? slice.call(value) : value; } var type = typeof value; if (value && value.length !== undefined && type !== 'string' && (type !== 'function' || !value.apply)) { return ExtArray.toArray(value); } return [ value ]; }, remove: function(array, item) { var index = ExtArray.indexOf(array, item); if (index !== -1) { erase(array, index, 1); } return array; }, removeAt: function(array, index, count) { var len = array.length; if (index >= 0 && index < len) { count = count || 1; count = Math.min(count, len - index); erase(array, index, count); } return array; }, include: function(array, item) { if (!ExtArray.contains(array, item)) { array.push(item); } }, clone: function(array) { return slice.call(array); }, merge: function() { var args = slice.call(arguments), array = [], i, ln; for (i = 0 , ln = args.length; i < ln; i++) { array = array.concat(args[i]); } return ExtArray.unique(array); }, intersect: function() { var intersection = [], arrays = slice.call(arguments), arraysLength, array, arrayLength, minArray, minArrayIndex, minArrayCandidate, minArrayLength, element, elementCandidate, elementCount, i, j, k; if (!arrays.length) { return intersection; } arraysLength = arrays.length; for (i = minArrayIndex = 0; i < arraysLength; i++) { minArrayCandidate = arrays[i]; if (!minArray || minArrayCandidate.length < minArray.length) { minArray = minArrayCandidate; minArrayIndex = i; } } minArray = ExtArray.unique(minArray); erase(arrays, minArrayIndex, 1); minArrayLength = minArray.length; arraysLength = arrays.length; for (i = 0; i < minArrayLength; i++) { element = minArray[i]; elementCount = 0; for (j = 0; j < arraysLength; j++) { array = arrays[j]; arrayLength = array.length; for (k = 0; k < arrayLength; k++) { elementCandidate = array[k]; if (element === elementCandidate) { elementCount++; break; } } } if (elementCount === arraysLength) { intersection.push(element); } } return intersection; }, 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]) { erase(clone, j, 1); j--; ln--; } } } return clone; }, slice: ([ 1, 2 ].slice(1, undefined).length ? function(array, begin, end) { return slice.call(array, begin, end); } : function(array, begin, end) { if (typeof begin === 'undefined') { return slice.call(array); } if (typeof end === 'undefined') { return slice.call(array, begin); } return slice.call(array, begin, end); }), sort: function(array, sortFn) { return stableSort(array, sortFn || ExtArray.lexicalCompare); }, flatten: function(array) { var worker = []; function rFlatten(a) { var i, ln, v; for (i = 0 , ln = a.length; i < ln; i++) { v = a[i]; if (Ext.isArray(v)) { rFlatten(v); } else { worker.push(v); } } return worker; } return rFlatten(array); }, min: function(array, comparisonFn) { var min = array[0], i, ln, item; for (i = 0 , ln = array.length; i < ln; i++) { item = array[i]; if (comparisonFn) { if (comparisonFn(min, item) === 1) { min = item; } } else { if (item < min) { min = item; } } } 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 max; }, mean: function(array) { return array.length > 0 ? ExtArray.sum(array) / array.length : undefined; }, sum: function(array) { var sum = 0, i, ln, item; for (i = 0 , ln = array.length; i < ln; i++) { item = array[i]; sum += item; } return sum; }, toMap: function(array, getKey, scope) { var map = {}, i = array.length; if (!getKey) { while (i--) { map[array[i]] = i + 1; } } else if (typeof getKey === 'string') { while (i--) { map[array[i][getKey]] = i + 1; } } else { while (i--) { map[getKey.call(scope, array[i])] = i + 1; } } return map; }, toValueMap: function(array, getKey, scope, arrayify) { var map = {}, i = array.length, autoArray, alwaysArray, entry, fn, key, value; if (!getKey) { while (i--) { value = array[i]; map[value] = value; } } else { if (!(fn = (typeof getKey !== 'string'))) { arrayify = scope; } alwaysArray = arrayify === 1; autoArray = arrayify === 2; while (i--) { value = array[i]; key = fn ? getKey.call(scope, value) : value[getKey]; if (alwaysArray) { if (key in map) { map[key].push(value); } else { map[key] = [ value ]; } } else if (autoArray && (key in map)) { if ((entry = map[key]) instanceof Array) { entry.push(value); } else { map[key] = [ entry, value ]; } } else { map[key] = value; } } } return map; }, _replaceSim: replaceSim, _spliceSim: spliceSim, erase: erase, insert: function(array, index, items) { return replace(array, index, 0, items); }, replace: replace, splice: splice, push: function(target) { var len = arguments.length, i = 1, newItem; if (target === undefined) { target = []; } else if (!Ext.isArray(target)) { target = [ target ]; } for (; i < len; i++) { newItem = arguments[i]; Array.prototype.push[Ext.isIterable(newItem) ? 'apply' : 'call'](target, newItem); } return target; }, numericSortFn: function(a, b) { return a - b; } }; Ext.each = ExtArray.each; ExtArray.union = ExtArray.merge; Ext.min = ExtArray.min; Ext.max = ExtArray.max; Ext.sum = ExtArray.sum; Ext.mean = ExtArray.mean; Ext.flatten = ExtArray.flatten; Ext.clean = ExtArray.clean; Ext.unique = ExtArray.unique; Ext.pluck = ExtArray.pluck; Ext.toArray = function() { return ExtArray.toArray.apply(ExtArray, arguments); }; return ExtArray; }()); Ext.Assert = { falsey: function(b, msg) { if (b) { Ext.Error.raise(msg || ('Expected a falsey value but was ' + b)); } }, falseyProp: function(object, property) { Ext.Assert.truthy(object); var b = object[property]; if (b) { if (object.$className) { property = object.$className + '#' + property; } Ext.Error.raise('Expected a falsey value for ' + property + ' but was ' + b); } }, truthy: function(b, msg) { if (!b) { Ext.Error.raise(msg || ('Expected a truthy value but was ' + typeof b)); } }, truthyProp: function(object, property) { Ext.Assert.truthy(object); var b = object[property]; if (!b) { if (object.$className) { property = object.$className + '#' + property; } Ext.Error.raise('Expected a truthy value for ' + property + ' but was ' + typeof b); } } }; (function() { function makeAssert(name, kind) { var testFn = Ext[name], def; return function(value, msg) { if (!testFn(value)) { Ext.Error.raise(msg || def || (def = 'Expected value to be ' + kind)); } }; } function makeAssertProp(name, kind) { var testFn = Ext[name], def; return function(object, prop) { Ext.Assert.truthy(object); if (!testFn(object[prop])) { Ext.Error.raise(def || (def = 'Expected ' + (object.$className ? object.$className + '#' : '') + prop + ' to be ' + kind)); } }; } function makeNotAssert(name, kind) { var testFn = Ext[name], def; return function(value, msg) { if (testFn(value)) { Ext.Error.raise(msg || def || (def = 'Expected value to NOT be ' + kind)); } }; } function makeNotAssertProp(name, kind) { var testFn = Ext[name], def; return function(object, prop) { Ext.Assert.truthy(object); if (testFn(object[prop])) { Ext.Error.raise(def || (def = 'Expected ' + (object.$className ? object.$className + '#' : '') + prop + ' to NOT be ' + kind)); } }; } for (var name in Ext) { if (name.substring(0, 2) == "is" && Ext.isFunction(Ext[name])) { var kind = name.substring(2); Ext.Assert[name] = makeAssert(name, kind); Ext.Assert[name + 'Prop'] = makeAssertProp(name, kind); Ext.Assert['isNot' + kind] = makeNotAssert(name, kind); Ext.Assert['isNot' + kind + 'Prop'] = makeNotAssertProp(name, kind); } } }()); Ext.String = (function() { var 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, escapeRegexRe = /([-.*+?\^${}()|\[\]\/\\])/g, basicTrimRe = /^\s+|\s+$/g, whitespaceRe = /\s+/, varReplace = /(^[^a-z]*|[^\w])/gi, charToEntity, entityToChar, charToEntityRegex, entityToCharRegex, htmlEncodeReplaceFn = function(match, capture) { return charToEntity[capture]; }, htmlDecodeReplaceFn = function(match, capture) { return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10)); }, boundsCheck = function(s, other) { if (s === null || s === undefined || other === null || other === undefined) { return false; } return other.length <= s.length; }, ExtString; return ExtString = { insert: function(s, value, index) { if (!s) { return value; } if (!value) { return s; } var len = s.length; if (!index && index !== 0) { index = len; } if (index < 0) { index *= -1; if (index >= len) { index = 0; } else { index = len - index; } } if (index === 0) { s = value + s; } else if (index >= s.length) { s += value; } else { s = s.substr(0, index) + value + s.substr(index); } return s; }, startsWith: function(s, start, ignoreCase) { var result = boundsCheck(s, start); if (result) { if (ignoreCase) { s = s.toLowerCase(); start = start.toLowerCase(); } result = s.lastIndexOf(start, 0) === 0; } return result; }, endsWith: function(s, end, ignoreCase) { var result = boundsCheck(s, end); if (result) { if (ignoreCase) { s = s.toLowerCase(); end = end.toLowerCase(); } result = s.indexOf(end, s.length - end.length) !== -1; } return result; }, createVarName: function(s) { return s.replace(varReplace, ''); }, htmlEncode: function(value) { return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn); }, htmlDecode: function(value) { return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn); }, hasHtmlCharacters: function(s) { return charToEntityRegex.test(s); }, addCharacterEntities: function(newEntities) { var charKeys = [], entityKeys = [], key, echar; for (key in newEntities) { echar = newEntities[key]; entityToChar[key] = echar; charToEntity[echar] = key; charKeys.push(echar); entityKeys.push(key); } charToEntityRegex = new RegExp('(' + charKeys.join('|') + ')', 'g'); entityToCharRegex = new RegExp('(' + entityKeys.join('|') + '|&#[0-9]{1,5};' + ')', 'g'); }, resetCharacterEntities: function() { charToEntity = {}; entityToChar = {}; this.addCharacterEntities({ '&': '&', '>': '>', '<': '<', '"': '"', ''': "'" }); }, urlAppend: function(url, string) { if (!Ext.isEmpty(string)) { return url + (url.indexOf('?') === -1 ? '?' : '&') + string; } return url; }, trim: function(string) { if (string) { string = string.replace(trimRegex, ""); } return string || ''; }, capitalize: function(string) { if (string) { string = string.charAt(0).toUpperCase() + string.substr(1); } return string || ''; }, uncapitalize: function(string) { if (string) { string = string.charAt(0).toLowerCase() + string.substr(1); } return string || ''; }, ellipsis: function(value, length, word) { if (value && value.length > length) { if (word) { var vs = value.substr(0, length - 2), index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?')); if (index !== -1 && index >= (length - 15)) { return vs.substr(0, index) + "..."; } } return value.substr(0, length - 3) + "..."; } return value; }, escapeRegex: function(string) { return string.replace(escapeRegexRe, "\\$1"); }, createRegex: function(value, startsWith, endsWith, ignoreCase) { var ret = value; if (value != null && !value.exec) { ret = ExtString.escapeRegex(String(value)); if (startsWith !== false) { ret = '^' + ret; } if (endsWith !== false) { ret += '$'; } ret = new RegExp(ret, (ignoreCase !== false) ? 'i' : ''); } return ret; }, escape: function(string) { return string.replace(escapeRe, "\\$1"); }, toggle: function(string, value, other) { return string === value ? other : value; }, leftPad: function(string, size, character) { var result = String(string); character = character || " "; while (result.length < size) { result = character + result; } return result; }, repeat: function(pattern, count, sep) { if (count < 1) { count = 0; } for (var buf = [], i = count; i--; ) { buf.push(pattern); } return buf.join(sep || ''); }, splitWords: function(words) { if (words && typeof words == 'string') { return words.replace(basicTrimRe, '').split(whitespaceRe); } return words || []; } }; }()); Ext.String.resetCharacterEntities(); Ext.htmlEncode = Ext.String.htmlEncode; Ext.htmlDecode = Ext.String.htmlDecode; Ext.urlAppend = Ext.String.urlAppend; Ext.Date = (function() { var utilDate, nativeDate = Date, stripEscapeRe = /(\\.)/g, hourInfoRe = /([gGhHisucUOPZ]|MS)/, dateInfoRe = /([djzmnYycU]|MS)/, slashRe = /\\/gi, numberTokenRe = /\{(\d+)\}/g, MSFormatRe = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/'), pad = Ext.String.leftPad, code = [ "var me = this, dt, y, m, d, h, i, s, ms, o, O, z, zz, u, v, W, year, jan4, week1monday, daysInMonth, dayMatched,", "def = me.defaults,", "from = Ext.Number.from,", "results = String(input).match(me.parseRegexes[{0}]);", "if(results){", "{1}", "if(u != null){", "v = new Date(u * 1000);", "}else{", "dt = me.clearTime(new Date);", "y = from(y, from(def.y, dt.getFullYear()));", "m = from(m, from(def.m - 1, dt.getMonth()));", "dayMatched = d !== undefined;", "d = from(d, from(def.d, dt.getDate()));", "if (!dayMatched) {", "dt.setDate(1);", "dt.setMonth(m);", "dt.setFullYear(y);", "daysInMonth = me.getDaysInMonth(dt);", "if (d > daysInMonth) {", "d = daysInMonth;", "}", "}", "h = from(h, from(def.h, dt.getHours()));", "i = from(i, from(def.i, dt.getMinutes()));", "s = from(s, from(def.s, dt.getSeconds()));", "ms = from(ms, from(def.ms, dt.getMilliseconds()));", "if(z >= 0 && y >= 0){", "v = me.add(new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms), me.YEAR, y < 100 ? y - 100 : 0);", "v = !strict? v : (strict === true && (z <= 364 || (me.isLeapYear(v) && z <= 365))? me.add(v, me.DAY, z) : null);", "}else if(strict === true && !me.isValid(y, m + 1, d, h, i, s, ms)){", "v = null;", "}else{", "if (W) {", "year = y || (new Date()).getFullYear();", "jan4 = new Date(year, 0, 4, 0, 0, 0);", "d = jan4.getDay();", "week1monday = new Date(jan4.getTime() - ((d === 0 ? 6 : d - 1) * 86400000));", "v = Ext.Date.clearTime(new Date(week1monday.getTime() + ((W - 1) * 604800000 + 43200000)));", "} else {", "v = me.add(new Date(y < 100 ? 100 : y, m, d, h, i, s, ms), me.YEAR, y < 100 ? y - 100 : 0);", "}", "}", "}", "}", "if(v){", "if(zz != null){", "v = me.add(v, me.SECOND, -v.getTimezoneOffset() * 60 - zz);", "}else if(o){", "v = me.add(v, me.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));", "}", "}", "return (v != null) ? v : null;" ].join('\n'); if (!Date.prototype.toISOString) { Date.prototype.toISOString = function() { var me = this; return pad(me.getUTCFullYear(), 4, '0') + '-' + pad(me.getUTCMonth() + 1, 2, '0') + '-' + pad(me.getUTCDate(), 2, '0') + 'T' + pad(me.getUTCHours(), 2, '0') + ':' + pad(me.getUTCMinutes(), 2, '0') + ':' + pad(me.getUTCSeconds(), 2, '0') + '.' + pad(me.getUTCMilliseconds(), 3, '0') + 'Z'; }; } function xf(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(numberTokenRe, function(m, i) { return args[i]; }); } return utilDate = { now: nativeDate.now, toString: function(date) { if (!date) { date = new nativeDate(); } 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'); }, getElapsed: function(dateA, dateB) { return Math.abs(dateA - (dateB || utilDate.now())); }, useStrict: false, 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) }; }, parseFunctions: { "MS": function(input, strict) { var r = (input || '').match(MSFormatRe); return r ? new nativeDate(((r[1] || '') + r[2]) * 1) : null; }, "time": function(input, strict) { var num = parseInt(input, 10); if (num || num === 0) { return new nativeDate(num); } return null; }, "timestamp": function(input, strict) { var num = parseInt(input, 10); if (num || num === 0) { return new nativeDate(num * 1000); } return null; } }, parseRegexes: [], formatFunctions: { "MS": function() { return '\\/Date(' + this.getTime() + ')\\/'; }, "time": function() { return this.getTime().toString(); }, "timestamp": function() { return utilDate.format(this, 'U'); } }, y2kYear: 50, MILLI: "ms", SECOND: "s", MINUTE: "mi", HOUR: "h", DAY: "d", MONTH: "mo", YEAR: "y", defaults: {}, dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], monthNames: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], monthNumbers: { January: 0, Jan: 0, February: 1, Feb: 1, March: 2, Mar: 2, April: 3, Apr: 3, May: 4, June: 5, Jun: 5, July: 6, Jul: 6, August: 7, Aug: 7, September: 8, Sep: 8, October: 9, Oct: 9, November: 10, Nov: 10, December: 11, Dec: 11 }, defaultFormat: "m/d/Y", getShortMonthName: function(month) { return utilDate.monthNames[month].substring(0, 3); }, getShortDayName: function(day) { return utilDate.dayNames[day].substring(0, 3); }, getMonthNumber: function(name) { return utilDate.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()]; }, formatContainsHourInfo: function(format) { return hourInfoRe.test(format.replace(stripEscapeRe, '')); }, formatContainsDateInfo: function(format) { return dateInfoRe.test(format.replace(stripEscapeRe, '')); }, unescapeFormat: function(format) { return format.replace(slashRe, ''); }, formatCodes: { d: "Ext.String.leftPad(m.getDate(), 2, '0')", D: "Ext.Date.getShortDayName(m.getDay())", j: "m.getDate()", l: "Ext.Date.dayNames[m.getDay()]", N: "(m.getDay() ? m.getDay() : 7)", S: "Ext.Date.getSuffix(m)", w: "m.getDay()", z: "Ext.Date.getDayOfYear(m)", W: "Ext.String.leftPad(Ext.Date.getWeekOfYear(m), 2, '0')", F: "Ext.Date.monthNames[m.getMonth()]", m: "Ext.String.leftPad(m.getMonth() + 1, 2, '0')", M: "Ext.Date.getShortMonthName(m.getMonth())", n: "(m.getMonth() + 1)", t: "Ext.Date.getDaysInMonth(m)", L: "(Ext.Date.isLeapYear(m) ? 1 : 0)", o: "(m.getFullYear() + (Ext.Date.getWeekOfYear(m) == 1 && m.getMonth() > 0 ? +1 : (Ext.Date.getWeekOfYear(m) >= 52 && m.getMonth() < 11 ? -1 : 0)))", Y: "Ext.String.leftPad(m.getFullYear(), 4, '0')", y: "('' + m.getFullYear()).substring(2, 4)", a: "(m.getHours() < 12 ? 'am' : 'pm')", A: "(m.getHours() < 12 ? 'AM' : 'PM')", g: "((m.getHours() % 12) ? m.getHours() % 12 : 12)", G: "m.getHours()", h: "Ext.String.leftPad((m.getHours() % 12) ? m.getHours() % 12 : 12, 2, '0')", H: "Ext.String.leftPad(m.getHours(), 2, '0')", i: "Ext.String.leftPad(m.getMinutes(), 2, '0')", s: "Ext.String.leftPad(m.getSeconds(), 2, '0')", u: "Ext.String.leftPad(m.getMilliseconds(), 3, '0')", O: "Ext.Date.getGMTOffset(m)", P: "Ext.Date.getGMTOffset(m, true)", T: "Ext.Date.getTimezone(m)", Z: "(m.getTimezoneOffset() * -60)", c: function() { var c = "Y-m-dTH:i:sP", code = [], i, l = c.length, e; for (i = 0; i < l; ++i) { e = c.charAt(i); code.push(e === "T" ? "'T'" : utilDate.getFormatCode(e)); } return code.join(" + "); }, C: function() { return 'm.toISOString()'; }, U: "Math.round(m.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 nativeDate(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].call(utilDate, 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 = '', i; for (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 { if (ch === '\n') { code.push("'\\n'"); } else { code.push(utilDate.getFormatCode(ch)); } } } utilDate.formatFunctions[format] = Ext.functionFactory("var m=this;return " + code.join('+')); }, createParser: function(format) { var regexNum = utilDate.parseRegexes.length, currentGroup = 1, calc = [], regex = [], special = false, ch = "", i = 0, len = format.length, atEnd = [], obj; for (; i < len; ++i) { ch = format.charAt(i); if (!special && ch === "\\") { special = true; } else if (special) { special = false; regex.push(Ext.String.escape(ch)); } else { obj = utilDate.formatCodeToRegex(ch, currentGroup); currentGroup += obj.g; regex.push(obj.s); if (obj.g && obj.c) { if (obj.calcAtEnd) { atEnd.push(obj.c); } else { calc.push(obj.c); } } } } calc = calc.concat(atEnd); 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: "(3[0-1]|[1-2][0-9]|0[1-9])" }, j: { g: 1, c: "d = parseInt(results[{0}], 10);\n", s: "(3[0-1]|[1-2][0-9]|[1-9])" }, 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: 1, c: "W = parseInt(results[{0}], 10);\n", s: "(\\d{2})" }, F: function() { return { g: 1, c: "m = parseInt(me.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: "(1[0-2]|0[1-9])" }, n: { g: 1, c: "m = parseInt(results[{0}], 10) - 1;\n", s: "(1[0-2]|[1-9])" }, t: { g: 0, c: null, s: "(?:\\d{2})" }, L: { g: 0, c: null, s: "(?:1|0)" }, o: { g: 1, c: "y = parseInt(results[{0}], 10);\n", s: "(\\d{4})" }, 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 > me.y2kYear ? 1900 + ty : 2000 + ty;\n", s: "(\\d{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)", calcAtEnd: true }, 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)", calcAtEnd: true }, g: { g: 1, c: "h = parseInt(results[{0}], 10);\n", s: "(1[0-2]|[0-9])" }, G: { g: 1, c: "h = parseInt(results[{0}], 10);\n", s: "(2[0-3]|1[0-9]|[0-9])" }, h: { g: 1, c: "h = parseInt(results[{0}], 10);\n", s: "(1[0-2]|0[1-9])" }, H: { g: 1, c: "h = parseInt(results[{0}], 10);\n", s: "(2[0-3]|[0-1][0-9])" }, i: { g: 1, c: "i = parseInt(results[{0}], 10);\n", s: "([0-5][0-9])" }, s: { g: 1, c: "s = parseInt(results[{0}], 10);\n", s: "([0-5][0-9])" }, 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,5}" }, 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') } ], i, l; for (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); }, isEqual: function(date1, date2) { if (date1 && date2) { return (date1.getTime() === date2.getTime()); } return !(date1 || date2); }, format: function(date, format) { var formatFunctions = utilDate.formatFunctions; if (!Ext.isDate(date)) { return ''; } if (formatFunctions[format] == null) { utilDate.createFormat(format); } return formatFunctions[format].call(date) + ''; }, getTimezone: function(date) { return date.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,5})(?:[\-+][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 = utilDate.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 = 86400000, ms7d = 7 * ms1d; return function(date) { var DC3 = nativeDate.UTC(date.getFullYear(), date.getMonth(), date.getDate() + 3) / ms1d, AWN = Math.floor(DC3 / 7), Wyr = new nativeDate(AWN * ms7d).getUTCFullYear(); return AWN - Math.floor(nativeDate.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 nativeDate(date.getFullYear(), date.getMonth(), 1); }, getLastDateOfMonth: function(date) { return new nativeDate(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 nativeDate(date.getTime()); }, isDST: function(date) { return new nativeDate(date.getFullYear(), 0, 1).getTimezoneOffset() !== date.getTimezoneOffset(); }, clearTime: function(date, clone) { if (clone) { return utilDate.clearTime(utilDate.clone(date)); } var d = date.getDate(), hr, c; date.setHours(0); date.setMinutes(0); date.setSeconds(0); date.setMilliseconds(0); if (date.getDate() !== d) { for (hr = 1 , c = utilDate.add(date, utilDate.HOUR, hr); c.getDate() !== d; hr++ , c = utilDate.add(date, utilDate.HOUR, hr)){} date.setDate(d); date.setHours(c.getHours()); } return date; }, add: function(date, interval, value) { var d = utilDate.clone(date), day, decimalValue, base = 0; if (!interval || value === 0) { return d; } decimalValue = value - parseInt(value, 10); value = parseInt(value, 10); if (value) { switch (interval.toLowerCase()) { case utilDate.MILLI: d.setTime(d.getTime() + value); break; case utilDate.SECOND: d.setTime(d.getTime() + value * 1000); break; case utilDate.MINUTE: d.setTime(d.getTime() + value * 60 * 1000); break; case utilDate.HOUR: d.setTime(d.getTime() + value * 60 * 60 * 1000); break; case utilDate.DAY: d.setDate(d.getDate() + value); break; case utilDate.MONTH: day = date.getDate(); if (day > 28) { day = Math.min(day, utilDate.getLastDateOfMonth(utilDate.add(utilDate.getFirstDateOfMonth(date), utilDate.MONTH, value)).getDate()); }; d.setDate(day); d.setMonth(date.getMonth() + value); break; case utilDate.YEAR: day = date.getDate(); if (day > 28) { day = Math.min(day, utilDate.getLastDateOfMonth(utilDate.add(utilDate.getFirstDateOfMonth(date), utilDate.YEAR, value)).getDate()); }; d.setDate(day); d.setFullYear(date.getFullYear() + value); break; } } if (decimalValue) { switch (interval.toLowerCase()) { case utilDate.MILLI: base = 1; break; case utilDate.SECOND: base = 1000; break; case utilDate.MINUTE: base = 1000 * 60; break; case utilDate.HOUR: base = 1000 * 60 * 60; break; case utilDate.DAY: base = 1000 * 60 * 60 * 24; break; case utilDate.MONTH: day = utilDate.getDaysInMonth(d); base = 1000 * 60 * 60 * 24 * day; break; case utilDate.YEAR: day = (utilDate.isLeapYear(d) ? 366 : 365); base = 1000 * 60 * 60 * 24 * day; break; } if (base) { d.setTime(d.getTime() + base * decimalValue); } } return d; }, subtract: function(date, interval, value) { return utilDate.add(date, interval, -value); }, between: function(date, start, end) { var t = date.getTime(); return start.getTime() <= t && t <= end.getTime(); }, compat: function() { var p, 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' ], sLen = statics.length, pLen = proto.length, stat, prot, s; for (s = 0; s < sLen; s++) { stat = statics[s]; nativeDate[stat] = utilDate[stat]; } for (p = 0; p < pLen; p++) { prot = proto[p]; nativeDate.prototype[prot] = function() { var args = Array.prototype.slice.call(arguments); args.unshift(this); return utilDate[prot].apply(utilDate, args); }; } }, diff: function(min, max, unit) { var est, diff = +max - min; switch (unit) { case utilDate.MILLI: return diff; case utilDate.SECOND: return Math.floor(diff / 1000); case utilDate.MINUTE: return Math.floor(diff / 60000); case utilDate.HOUR: return Math.floor(diff / 3600000); case utilDate.DAY: return Math.floor(diff / 86400000); case 'w': return Math.floor(diff / 604800000); case utilDate.MONTH: est = (max.getFullYear() * 12 + max.getMonth()) - (min.getFullYear() * 12 + min.getMonth()); if (utilDate.add(min, unit, est) > max) { return est - 1; }; return est; case utilDate.YEAR: est = max.getFullYear() - min.getFullYear(); if (utilDate.add(min, unit, est) > max) { return est - 1; } else { return est; }; } }, align: function(date, unit, step) { var num = new nativeDate(+date); switch (unit.toLowerCase()) { case utilDate.MILLI: return num; case utilDate.SECOND: num.setUTCSeconds(num.getUTCSeconds() - num.getUTCSeconds() % step); num.setUTCMilliseconds(0); return num; case utilDate.MINUTE: num.setUTCMinutes(num.getUTCMinutes() - num.getUTCMinutes() % step); num.setUTCSeconds(0); num.setUTCMilliseconds(0); return num; case utilDate.HOUR: num.setUTCHours(num.getUTCHours() - num.getUTCHours() % step); num.setUTCMinutes(0); num.setUTCSeconds(0); num.setUTCMilliseconds(0); return num; case utilDate.DAY: if (step === 7 || step === 14) { num.setUTCDate(num.getUTCDate() - num.getUTCDay() + 1); }; num.setUTCHours(0); num.setUTCMinutes(0); num.setUTCSeconds(0); num.setUTCMilliseconds(0); return num; case utilDate.MONTH: num.setUTCMonth(num.getUTCMonth() - (num.getUTCMonth() - 1) % step, 1); num.setUTCHours(0); num.setUTCMinutes(0); num.setUTCSeconds(0); num.setUTCMilliseconds(0); return num; case utilDate.YEAR: num.setUTCFullYear(num.getUTCFullYear() - num.getUTCFullYear() % step, 1, 1); num.setUTCHours(0); num.setUTCMinutes(0); num.setUTCSeconds(0); num.setUTCMilliseconds(0); return date; } } }; }()); Ext.Function = (function() { var lastTime = 0, animFrameId, animFrameHandlers = [], animFrameNoArgs = [], idSource = 0, animFrameMap = {}, win = window, requestAnimFrame = win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || function(callback) { var currTime = Ext.now(), timeToCall = Math.max(0, 16 - (currTime - lastTime)), id = win.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }, fireHandlers = function() { var len = animFrameHandlers.length, id, i, handler; animFrameId = null; for (i = 0; i < len; i++) { handler = animFrameHandlers[i]; id = handler[3]; if (animFrameMap[id]) { handler[0].apply(handler[1] || Ext.global, handler[2] || animFrameNoArgs); delete animFrameMap[id]; } } animFrameHandlers = animFrameHandlers.slice(len); }, fireElevatedHandlers = function() { Ext.elevateFunction(fireHandlers); }, ExtFunction = { flexSetter: function(setter) { return function(name, value) { var k, i; if (name !== null) { if (typeof name !== 'string') { for (k in name) { if (name.hasOwnProperty(k)) { setter.call(this, k, name[k]); } } if (Ext.enumerables) { for (i = Ext.enumerables.length; i--; ) { k = Ext.enumerables[i]; if (name.hasOwnProperty(k)) { setter.call(this, k, name[k]); } } } } else { setter.call(this, name, value); } } return this; }; }, bind: function(fn, scope, args, appendArgs) { if (arguments.length === 2) { return function() { return fn.apply(scope, arguments); }; } var method = fn, slice = Array.prototype.slice; return function() { var callArgs = args || arguments; if (appendArgs === true) { callArgs = slice.call(arguments, 0); callArgs = callArgs.concat(args); } else if (typeof appendArgs == 'number') { callArgs = slice.call(arguments, 0); Ext.Array.insert(callArgs, appendArgs, args); } return method.apply(scope || Ext.global, callArgs); }; }, bindCallback: function(callback, scope, args, delay, caller) { return function() { var a = Ext.Array.slice(arguments); return Ext.callback(callback, scope, args ? args.concat(a) : a, delay, caller); }; }, pass: function(fn, args, scope) { if (!Ext.isArray(args)) { if (Ext.isIterable(args)) { args = Ext.Array.clone(args); } else { args = args !== undefined ? [ args ] : []; } } return function() { var fnArgs = args.slice(); fnArgs.push.apply(fnArgs, arguments); return fn.apply(scope || this, fnArgs); }; }, alias: function(object, methodName) { return function() { return object[methodName].apply(object, arguments); }; }, clone: function(method) { return function() { return method.apply(this, arguments); }; }, createInterceptor: function(origFn, newFn, scope, returnValue) { if (!Ext.isFunction(newFn)) { return origFn; } else { returnValue = Ext.isDefined(returnValue) ? returnValue : null; return function() { var me = this, args = arguments; newFn.target = me; newFn.method = origFn; return (newFn.apply(scope || me || Ext.global, args) !== false) ? origFn.apply(me || Ext.global, args) : returnValue; }; } }, createDelayed: function(fn, delay, scope, args, appendArgs) { if (scope || args) { fn = Ext.Function.bind(fn, scope, args, appendArgs); } return function() { var me = this, args = Array.prototype.slice.call(arguments); setTimeout(function() { if (Ext.elevateFunction) { Ext.elevateFunction(fn, me, args); } else { fn.apply(me, args); } }, delay); }; }, defer: function(fn, millis, scope, args, appendArgs) { fn = Ext.Function.bind(fn, scope, args, appendArgs); if (millis > 0) { return setTimeout(function() { if (Ext.elevateFunction) { Ext.elevateFunction(fn); } else { fn(); } }, millis); } fn(); return 0; }, interval: function(fn, millis, scope, args, appendArgs) { fn = Ext.Function.bind(fn, scope, args, appendArgs); return setInterval(function() { if (Ext.elevateFunction) { Ext.elevateFunction(fn); } else { fn(); } }, millis); }, createSequence: function(originalFn, newFn, scope) { if (!newFn) { return originalFn; } else { return function() { var result = originalFn.apply(this, arguments); newFn.apply(scope || this, arguments); return result; }; } }, createBuffered: function(fn, buffer, scope, args) { var timerId; return function() { var callArgs = args || Array.prototype.slice.call(arguments, 0), me = scope || this; if (timerId) { clearTimeout(timerId); } timerId = setTimeout(function() { if (Ext.elevateFunction) { Ext.elevateFunction(fn, me, callArgs); } else { fn.apply(me, callArgs); } }, buffer); }; }, createAnimationFrame: function(fn, scope, args, queueStrategy) { var timerId; queueStrategy = queueStrategy || 3; return function() { var callArgs = args || Array.prototype.slice.call(arguments, 0); scope = scope || this; if (queueStrategy === 3 && timerId) { ExtFunction.cancelAnimationFrame(timerId); } if ((queueStrategy & 1) || !timerId) { timerId = ExtFunction.requestAnimationFrame(function() { timerId = null; fn.apply(scope, callArgs); }); } }; }, requestAnimationFrame: function(fn, scope, args) { var id = ++idSource, handler = Array.prototype.slice.call(arguments, 0); handler[3] = id; animFrameMap[id] = 1; animFrameHandlers.push(handler); if (!animFrameId) { animFrameId = requestAnimFrame(Ext.elevateFunction ? fireElevatedHandlers : fireHandlers); } return id; }, cancelAnimationFrame: function(id) { delete animFrameMap[id]; }, createThrottled: function(fn, interval, scope) { var lastCallTime = 0, elapsed, lastArgs, timer, execute = function() { if (Ext.elevateFunction) { Ext.elevateFunction(fn, scope, lastArgs); } else { fn.apply(scope, lastArgs); } lastCallTime = Ext.now(); timer = null; }; return function() { if (!scope) { scope = this; } elapsed = Ext.now() - lastCallTime; lastArgs = arguments; if (elapsed >= interval) { clearTimeout(timer); execute(); } else if (!timer) { timer = Ext.defer(execute, interval - elapsed); } }; }, createBarrier: function(count, fn, scope) { return function() { if (!--count) { fn.apply(scope, arguments); } }; }, interceptBefore: function(object, methodName, fn, scope) { var method = object[methodName] || Ext.emptyFn; return (object[methodName] = function() { var ret = fn.apply(scope || this, arguments); method.apply(this, arguments); return ret; }); }, interceptAfter: function(object, methodName, fn, scope) { var method = object[methodName] || Ext.emptyFn; return (object[methodName] = function() { method.apply(this, arguments); return fn.apply(scope || this, arguments); }); }, makeCallback: function(callback, scope) { if (!scope[callback]) { if (scope.$className) { Ext.Error.raise('No method "' + callback + '" on ' + scope.$className); } Ext.Error.raise('No method "' + callback + '"'); } return function() { return scope[callback].apply(scope, arguments); }; } }; Ext.defer = ExtFunction.defer; Ext.interval = ExtFunction.interval; Ext.pass = ExtFunction.pass; Ext.bind = ExtFunction.bind; Ext.deferCallback = ExtFunction.requestAnimationFrame; return ExtFunction; })(); Ext.Number = (new function() { var ExtNumber = this, isToFixedBroken = (0.9).toFixed() !== '1', math = Math, ClipDefault = { count: false, inclusive: false, wrap: true }; Ext.apply(ExtNumber, { Clip: { DEFAULT: ClipDefault, COUNT: Ext.applyIf({ count: true }, ClipDefault), INCLUSIVE: Ext.applyIf({ inclusive: true }, ClipDefault), NOWRAP: Ext.applyIf({ wrap: false }, ClipDefault) }, clipIndices: function(length, indices, options) { options = options || ClipDefault; var defaultValue = 0, wrap = options.wrap, begin, end, i; indices = indices || []; for (i = 0; i < 2; ++i) { begin = end; end = indices[i]; if (end == null) { end = defaultValue; } else if (i && options.count) { end += begin; end = (end > length) ? length : end; } else { if (wrap) { end = (end < 0) ? (length + end) : end; } if (i && options.inclusive) { ++end; } end = (end < 0) ? 0 : ((end > length) ? length : end); } defaultValue = length; } indices[0] = begin; indices[1] = (end < begin) ? begin : end; return indices; }, constrain: function(number, min, max) { var x = parseFloat(number); if (min === null) { min = number; } if (max === null) { max = number; } return (x < min) ? min : ((x > max) ? max : x); }, snap: function(value, increment, minValue, maxValue) { var m; if (value === undefined || value < minValue) { return minValue || 0; } if (increment) { m = value % increment; if (m !== 0) { value -= m; if (m * 2 >= increment) { value += increment; } else if (m * 2 < -increment) { value -= increment; } } } return ExtNumber.constrain(value, minValue, maxValue); }, snapInRange: function(value, increment, minValue, maxValue) { var tween; minValue = (minValue || 0); if (value === undefined || value < minValue) { return minValue; } if (increment && (tween = ((value - minValue) % increment))) { value -= tween; tween *= 2; if (tween >= increment) { value += increment; } } if (maxValue !== undefined) { if (value > (maxValue = ExtNumber.snapInRange(maxValue, increment, minValue))) { value = maxValue; } } return value; }, sign: function(x) { x = +x; if (x === 0 || isNaN(x)) { return x; } return (x > 0) ? 1 : -1; }, toFixed: isToFixedBroken ? function(value, precision) { precision = precision || 0; var pow = math.pow(10, precision); return (math.round(value * pow) / pow).toFixed(precision); } : function(value, precision) { return value.toFixed(precision); }, from: function(value, defaultValue) { if (isFinite(value)) { value = parseFloat(value); } return !isNaN(value) ? value : defaultValue; }, randomInt: function(from, to) { return math.floor(math.random() * (to - from + 1) + from); }, correctFloat: function(n) { return parseFloat(n.toPrecision(14)); } }); Ext.num = function() { return ExtNumber.from.apply(this, arguments); }; }()); (function() { var TemplateClass = function() {}, queryRe = /^\?/, keyRe = /(\[):?([^\]]*)\]/g, nameRe = /^([^\[]+)/, plusRe = /\+/g, ExtObject = Ext.Object = { chain: Object.create || function(object) { TemplateClass.prototype = object; var result = new TemplateClass(); TemplateClass.prototype = null; return result; }, clear: function(object) { for (var key in object) { delete object[key]; } return object; }, freeze: Object.freeze ? function(obj, deep) { if (obj && typeof obj === 'object' && !Object.isFrozen(obj)) { Object.freeze(obj); if (deep) { for (var name in obj) { ExtObject.freeze(obj[name], deep); } } } return obj; } : Ext.identityFn, toQueryObjects: function(name, value, recursive) { var self = ExtObject.toQueryObjects, objects = [], i, ln; 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] }); } } } 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] }); } } } } else { objects.push({ name: name, value: 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)); } } for (j = 0 , ln = paramObjects.length; j < ln; j++) { paramObject = paramObjects[j]; value = paramObject.value; if (Ext.isEmpty(value)) { value = ''; } else if (Ext.isDate(value)) { value = Ext.Date.toString(value); } params.push(encodeURIComponent(paramObject.name) + '=' + encodeURIComponent(String(value))); } return params.join('&'); }, fromQueryString: function(queryString, recursive) { var parts = queryString.replace(queryRe, '').split('&'), object = {}, temp, components, name, value, i, ln, part, j, subLn, matchedKeys, matchedName, keys, key, nextKey; for (i = 0 , ln = parts.length; i < ln; i++) { part = parts[i]; if (part.length > 0) { components = part.split('='); name = components[0]; name = name.replace(plusRe, '%20'); name = decodeURIComponent(name); value = components[1]; if (value !== undefined) { value = value.replace(plusRe, '%20'); value = decodeURIComponent(value); } else { value = ''; } if (!recursive) { if (object.hasOwnProperty(name)) { if (!Ext.isArray(object[name])) { object[name] = [ object[name] ]; } object[name].push(value); } else { object[name] = value; } } else { matchedKeys = name.match(keyRe); matchedName = name.match(nameRe); if (!matchedName) { throw new Error('[Ext.Object.fromQueryString] Malformed query string given, failed parsing name from "' + part + '"'); } name = matchedName[0]; keys = []; if (matchedKeys === null) { object[name] = value; continue; } 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); temp = object; for (j = 0 , subLn = keys.length; j < subLn; j++) { key = keys[j]; 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 === '') ? [] : {}; } temp = temp[key]; } } } } } return object; }, each: function(object, fn, scope) { var enumerables = Ext.enumerables, i, property; if (object) { scope = scope || object; for (property in object) { if (object.hasOwnProperty(property)) { if (fn.call(scope, property, object[property], object) === false) { return; } } } if (enumerables) { for (i = enumerables.length; i--; ) { if (object.hasOwnProperty(property = enumerables[i])) { if (fn.call(scope, property, object[property], object) === false) { return; } } } } } }, eachValue: function(object, fn, scope) { var enumerables = Ext.enumerables, i, property; scope = scope || object; for (property in object) { if (object.hasOwnProperty(property)) { if (fn.call(scope, object[property]) === false) { return; } } } if (enumerables) { for (i = enumerables.length; i--; ) { if (object.hasOwnProperty(property = enumerables[i])) { if (fn.call(scope, object[property]) === false) { return; } } } } }, merge: function(destination) { var i = 1, ln = arguments.length, mergeFn = ExtObject.merge, cloneFn = Ext.clone, object, key, value, sourceKey; for (; i < ln; i++) { object = arguments[i]; for (key in object) { value = object[key]; if (value && value.constructor === Object) { sourceKey = destination[key]; if (sourceKey && sourceKey.constructor === Object) { mergeFn(sourceKey, value); } else { destination[key] = cloneFn(value); } } else { destination[key] = value; } } } return destination; }, mergeIf: function(destination) { var i = 1, ln = arguments.length, cloneFn = Ext.clone, object, key, value; for (; i < ln; i++) { object = arguments[i]; for (key in object) { if (!(key in destination)) { value = object[key]; if (value && value.constructor === Object) { destination[key] = cloneFn(value); } else { destination[key] = value; } } } } return destination; }, getAllKeys: function(object) { var keys = [], property; for (property in object) { keys.push(property); } return keys; }, getKey: function(object, value) { for (var property in object) { if (object.hasOwnProperty(property) && object[property] === value) { return property; } } return null; }, getValues: function(object) { var values = [], property; for (property in object) { if (object.hasOwnProperty(property)) { values.push(object[property]); } } return values; }, getKeys: (typeof Object.keys == 'function') ? function(object) { if (!object) { return []; } return Object.keys(object); } : function(object) { var keys = [], property; for (property in object) { if (object.hasOwnProperty(property)) { keys.push(property); } } return keys; }, getSize: function(object) { var size = 0, property; for (property in object) { if (object.hasOwnProperty(property)) { size++; } } return size; }, isEmpty: function(object) { for (var key in object) { if (object.hasOwnProperty(key)) { return false; } } return true; }, equals: (function() { var check = function(o1, o2) { var key; for (key in o1) { if (o1.hasOwnProperty(key)) { if (o1[key] !== o2[key]) { return false; } } } return true; }; return function(object1, object2) { if (object1 === object2) { return true; } if (object1 && object2) { return check(object1, object2) && check(object2, object1); } else if (!object1 && !object2) { return object1 === object2; } else { return false; } }; })(), fork: function(obj) { var ret, key, value; if (obj && obj.constructor === Object) { ret = ExtObject.chain(obj); for (key in obj) { value = obj[key]; if (value) { if (value.constructor === Object) { ret[key] = ExtObject.fork(value); } else if (value instanceof Array) { ret[key] = Ext.Array.clone(value); } } } } else { ret = obj; } return ret; }, defineProperty: ('defineProperty' in Object) ? Object.defineProperty : function(object, name, descriptor) { if (!Object.prototype.__defineGetter__) { return; } if (descriptor.get) { object.__defineGetter__(name, descriptor.get); } if (descriptor.set) { object.__defineSetter__(name, descriptor.set); } }, classify: function(object) { var prototype = object, objectProperties = [], propertyClassesMap = {}, objectClass = function() { var i = 0, ln = objectProperties.length, property; for (; i < ln; i++) { property = objectProperties[i]; this[property] = new propertyClassesMap[property](); } }, key, value; for (key in object) { if (object.hasOwnProperty(key)) { value = object[key]; if (value && value.constructor === Object) { objectProperties.push(key); propertyClassesMap[key] = ExtObject.classify(value); } } } objectClass.prototype = prototype; return objectClass; } }; Ext.merge = Ext.Object.merge; Ext.mergeIf = Ext.Object.mergeIf; }()); Ext.apply(Ext, { _namedScopes: { 'this': { isThis: 1 }, controller: { isController: 1 }, self: { isSelf: 1 }, 'self.controller': { isSelf: 1, isController: 1 } }, escapeId: (function() { var validIdRe = /^[a-zA-Z_][a-zA-Z0-9_\-]*$/i, escapeRx = /([\W]{1})/g, leadingNumRx = /^(\d)/g, escapeFn = function(match, capture) { return "\\" + capture; }, numEscapeFn = function(match, capture) { return '\\00' + capture.charCodeAt(0).toString(16) + ' '; }; return function(id) { return validIdRe.test(id) ? id : id.replace(escapeRx, escapeFn).replace(leadingNumRx, numEscapeFn); }; }()), callback: function(callback, scope, args, delay, caller, defaultScope) { if (!callback) { return; } var namedScope = (scope in Ext._namedScopes); if (callback.charAt) { if ((!scope || namedScope) && caller) { scope = caller.resolveListenerScope(namedScope ? scope : defaultScope); } if (!scope || !Ext.isObject(scope)) { Ext.Error.raise('Named method "' + callback + '" requires a scope object'); } if (!Ext.isFunction(scope[callback])) { Ext.Error.raise('No method named "' + callback + '" on ' + (scope.$className || 'scope object')); } callback = scope[callback]; } else if (namedScope) { scope = defaultScope || caller; } else if (!scope) { scope = caller; } var ret; if (callback && Ext.isFunction(callback)) { scope = scope || Ext.global; if (delay) { Ext.defer(callback, delay, scope, args); } else if (Ext.elevateFunction) { ret = Ext.elevateFunction(callback, scope, args); } else if (args) { ret = callback.apply(scope, args); } else { ret = callback.call(scope); } } return ret; }, coerce: function(from, to) { var fromType = Ext.typeOf(from), toType = Ext.typeOf(to), isString = typeof from === 'string'; if (fromType !== toType) { switch (toType) { case 'string': return String(from); case 'number': return Number(from); case 'boolean': return isString && (!from || from === 'false') ? false : Boolean(from); case 'null': return isString && (!from || from === 'null') ? null : from; case 'undefined': return isString && (!from || from === 'undefined') ? undefined : from; case 'date': return isString && isNaN(from) ? Ext.Date.parse(from, Ext.Date.defaultFormat) : Date(Number(from)); } } return from; }, copyTo: function(dest, source, names, usePrototypeKeys) { if (typeof names === 'string') { names = names.split(Ext.propertyNameSplitRe); } for (var name, i = 0, n = names ? names.length : 0; i < n; i++) { name = names[i]; if (usePrototypeKeys || source.hasOwnProperty(name)) { dest[name] = source[name]; } } return dest; }, propertyNameSplitRe: /[,;\s]+/, copyToIf: function(destination, source, names) { if (typeof names === 'string') { names = names.split(Ext.propertyNameSplitRe); } for (var name, i = 0, n = names ? names.length : 0; i < n; i++) { name = names[i]; if (destination[name] === undefined) { destination[name] = source[name]; } } return destination; }, extend: (function() { var objectConstructor = Object.prototype.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; }; }()), 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 { Ext.Object.each.call(Ext.Object, object, fn, scope); } }, urlEncode: function() { var args = Ext.Array.from(arguments), prefix = ''; if (Ext.isString(args[1])) { prefix = args[1] + '&'; args[1] = false; } return prefix + Ext.Object.toQueryString.apply(Ext.Object, args); }, urlDecode: function() { return Ext.Object.fromQueryString.apply(Ext.Object, arguments); }, getScrollbarSize: function(force) { if (!Ext.isDomReady) { Ext.Error.raise("getScrollbarSize called before DomReady"); } var scrollbarSize = Ext._scrollbarSize; if (force || !scrollbarSize) { var db = document.body, div = document.createElement('div'); div.style.width = div.style.height = '100px'; div.style.overflow = 'scroll'; div.style.position = 'absolute'; db.appendChild(div); Ext._scrollbarSize = scrollbarSize = { width: div.offsetWidth - div.clientWidth, height: div.offsetHeight - div.clientHeight }; db.removeChild(div); } return scrollbarSize; }, typeOf: (function() { var nonWhitespaceRe = /\S/, toString = Object.prototype.toString, typeofTypes = { number: 1, string: 1, 'boolean': 1, 'undefined': 1 }, toStringTypes = { '[object Array]': 'array', '[object Date]': 'date', '[object Boolean]': 'boolean', '[object Number]': 'number', '[object RegExp]': 'regexp' }; return function(value) { if (value === null) { return 'null'; } var type = typeof value, ret, typeToString; if (typeofTypes[type]) { return type; } ret = toStringTypes[typeToString = toString.call(value)]; if (ret) { return ret; } if (type === 'function') { return 'function'; } if (type === 'object') { if (value.nodeType !== undefined) { if (value.nodeType === 3) { return nonWhitespaceRe.test(value.nodeValue) ? 'textnode' : 'whitespace'; } else { return 'element'; } } return 'object'; } Ext.Error.raise({ sourceClass: 'Ext', sourceMethod: 'typeOf', msg: 'Failed to determine the type of "' + value + '".' }); return typeToString; }; }()), factory: function(config, classReference, instance, aliasNamespace) { var manager = Ext.ClassManager, newInstance; if (!config || config.isInstance) { if (instance && instance !== config) { instance.destroy(); } return config; } if (aliasNamespace) { if (typeof config === 'string') { return manager.instantiateByAlias(aliasNamespace + '.' + config); } else if (Ext.isObject(config) && 'type' in config) { return manager.instantiateByAlias(aliasNamespace + '.' + config.type, config); } } if (config === true) { return instance || Ext.create(classReference); } if (!Ext.isObject(config)) { Ext.Logger.error("Invalid config, must be a valid config object"); } if ('xtype' in config) { newInstance = manager.instantiateByAlias('widget.' + config.xtype, config); } else if ('xclass' in config) { newInstance = Ext.create(config.xclass, config); } if (newInstance) { if (instance) { instance.destroy(); } return newInstance; } if (instance) { return instance.setConfig(config); } return Ext.create(classReference, config); }, log: (function() { var primitiveRe = /string|number|boolean/; function dumpObject(object, level, maxLevel, withFunctions) { var member, type, value, name, prefix, suffix, members = []; if (Ext.isArray(object)) { prefix = '['; suffix = ']'; } else if (Ext.isObject(object)) { prefix = '{'; suffix = '}'; } if (!maxLevel) { maxLevel = 3; } if (level > maxLevel) { return prefix + '...' + suffix; } level = level || 1; var spacer = (new Array(level)).join(' '); for (name in object) { if (object.hasOwnProperty(name)) { value = object[name]; type = typeof value; if (type === 'function') { if (!withFunctions) { continue; } member = type; } else if (type === 'undefined') { member = type; } else if (value === null || primitiveRe.test(type) || Ext.isDate(value)) { member = Ext.encode(value); } else if (Ext.isArray(value)) { member = this.dumpObject(value, level + 1, maxLevel, withFunctions); } else if (Ext.isObject(value)) { member = this.dumpObject(value, level + 1, maxLevel, withFunctions); } else { member = type; } members.push(spacer + name + ': ' + member); } } if (members.length) { return prefix + '\n ' + members.join(',\n ') + '\n' + spacer + suffix; } return prefix + suffix; } function log(message) { var options, dump, con = Ext.global.console, level = 'log', indent = log.indent || 0, prefix, stack, fn, out, max; log.indent = indent; if (typeof message !== 'string') { options = message; message = options.msg || ''; level = options.level || level; dump = options.dump; stack = options.stack; prefix = options.prefix; fn = options.fn; if (options.indent) { ++log.indent; } else if (options.outdent) { log.indent = indent = Math.max(indent - 1, 0); } if (dump && !(con && con.dir)) { message += dumpObject(dump); dump = null; } } if (arguments.length > 1) { message += Array.prototype.slice.call(arguments, 1).join(''); } if (prefix) { message = prefix + ' - ' + message; } message = indent ? Ext.String.repeat(' ', log.indentSize * indent) + message : message; if (level !== 'log') { message = '[' + level.charAt(0).toUpperCase() + '] ' + message; } if (fn) { message += '\nCaller: ' + fn.toString(); } if (con) { if (con[level]) { con[level](message); } else { con.log(message); } if (dump) { con.dir(dump); } if (stack && con.trace) { if (!con.firebug || level !== 'error') { con.trace(); } } } else if (Ext.isOpera) { opera.postError(message); } else { out = log.out; max = log.max; if (out.length >= max) { Ext.Array.erase(out, 0, out.length - 3 * Math.floor(max / 4)); } out.push(message); } ++log.count; ++log.counters[level]; } function logx(level, args) { if (typeof args[0] === 'string') { args.unshift({}); } args[0].level = level; log.apply(this, args); } log.error = function() { logx('error', Array.prototype.slice.call(arguments)); }; log.info = function() { logx('info', Array.prototype.slice.call(arguments)); }; log.warn = function() { logx('warn', Array.prototype.slice.call(arguments)); }; log.count = 0; log.counters = { error: 0, warn: 0, info: 0, log: 0 }; log.indentSize = 2; log.out = []; log.max = 750; return log; }()) || (function() { var nullLog = function() {}; nullLog.info = nullLog.warn = nullLog.error = Ext.emptyFn; return nullLog; }()) }); (function() { var checkVerTemp = [ '' ], endOfVersionRe = /([^\d\.])/, notDigitsRe = /[^\d]/g, plusMinusRe = /[\-+]/g, stripRe = /\s/g, underscoreRe = /_/g, Version; Ext.Version = Version = function(version, defaultMode) { var me = this, padModes = me.padModes, ch, i, pad, parts, release, releaseStartIndex, ver; if (version.isVersion) { version = version.version; } me.version = ver = String(version).toLowerCase().replace(underscoreRe, '.').replace(plusMinusRe, ''); ch = ver.charAt(0); if (ch in padModes) { ver = ver.substring(1); pad = padModes[ch]; } else { pad = defaultMode ? padModes[defaultMode] : 0; } me.pad = pad; releaseStartIndex = ver.search(endOfVersionRe); me.shortVersion = ver; if (releaseStartIndex !== -1) { me.release = release = ver.substr(releaseStartIndex, version.length); me.shortVersion = ver.substr(0, releaseStartIndex); release = Version.releaseValueMap[release] || release; } me.releaseValue = release || pad; me.shortVersion = me.shortVersion.replace(notDigitsRe, ''); me.parts = parts = ver.split('.'); for (i = parts.length; i--; ) { parts[i] = parseInt(parts[i], 10); } if (pad === Infinity) { parts.push(pad); } me.major = parts[0] || pad; me.minor = parts[1] || pad; me.patch = parts[2] || pad; me.build = parts[3] || pad; return me; }; Version.prototype = { isVersion: true, padModes: { '~': NaN, '^': Infinity }, release: '', compareTo: function(other) { var me = this, lhsPad = me.pad, lhsParts = me.parts, lhsLength = lhsParts.length, rhsVersion = other.isVersion ? other : new Version(other), rhsPad = rhsVersion.pad, rhsParts = rhsVersion.parts, rhsLength = rhsParts.length, length = Math.max(lhsLength, rhsLength), i, lhs, rhs; for (i = 0; i < length; i++) { lhs = (i < lhsLength) ? lhsParts[i] : lhsPad; rhs = (i < rhsLength) ? rhsParts[i] : rhsPad; if (lhs < rhs) { return -1; } if (lhs > rhs) { return 1; } } lhs = me.releaseValue; rhs = rhsVersion.releaseValue; if (lhs < rhs) { return -1; } if (lhs > rhs) { return 1; } return 0; }, toString: function() { return this.version; }, valueOf: function() { return this.version; }, getMajor: function() { return this.major; }, getMinor: function() { return this.minor; }, getPatch: function() { return this.patch; }, getBuild: function() { return this.build; }, getRelease: function() { return this.release; }, getReleaseValue: function() { return this.releaseValue; }, isGreaterThan: function(target) { return this.compareTo(target) > 0; }, isGreaterThanOrEqual: function(target) { return this.compareTo(target) >= 0; }, isLessThan: function(target) { return this.compareTo(target) < 0; }, isLessThanOrEqual: function(target) { return this.compareTo(target) <= 0; }, equals: function(target) { return this.compareTo(target) === 0; }, match: function(target) { target = String(target); return this.version.substr(0, target.length) === target; }, toArray: function() { var me = this; return [ me.getMajor(), me.getMinor(), me.getPatch(), me.getBuild(), me.getRelease() ]; }, getShortVersion: function() { return this.shortVersion; }, gt: function(target) { return this.compareTo(target) > 0; }, lt: function(target) { return this.compareTo(target) < 0; }, gtEq: function(target) { return this.compareTo(target) >= 0; }, ltEq: function(target) { return this.compareTo(target) <= 0; } }; Ext.apply(Version, { aliases: { from: { extjs: 'ext', core: 'sencha-core' }, to: { ext: [ 'extjs' ], 'sencha-core': [ 'core' ] } }, releaseValueMap: { dev: -6, alpha: -5, a: -5, beta: -4, b: -4, rc: -3, '#': -2, p: -1, pl: -1 }, getComponentValue: function(value) { return !value ? 0 : (isNaN(value) ? this.releaseValueMap[value] || value : parseInt(value, 10)); }, compare: function(current, target) { var ver = current.isVersion ? current : new Version(current); return ver.compareTo(target); }, set: function(collection, packageName, version) { var aliases = Version.aliases.to[packageName], ver = version.isVersion ? version : new Version(version), i; collection[packageName] = ver; if (aliases) { for (i = aliases.length; i-- > 0; ) { collection[aliases[i]] = ver; } } return ver; } }); Ext.apply(Ext, { compatVersions: {}, versions: {}, lastRegisteredVersion: null, getCompatVersion: function(packageName) { var versions = Ext.compatVersions, compat; if (!packageName) { compat = versions.ext || versions.touch || versions.core; } else { compat = versions[Version.aliases.from[packageName] || packageName]; } return compat || Ext.getVersion(packageName); }, setCompatVersion: function(packageName, version) { Version.set(Ext.compatVersions, packageName, version); }, setVersion: function(packageName, version) { Ext.lastRegisteredVersion = Version.set(Ext.versions, packageName, version); return this; }, getVersion: function(packageName) { var versions = Ext.versions; if (!packageName) { return versions.ext || versions.touch || versions.core; } return versions[Version.aliases.from[packageName] || packageName]; }, checkVersion: function(specs, matchAll) { var isArray = Ext.isArray(specs), aliases = Version.aliases.from, compat = isArray ? specs : checkVerTemp, length = compat.length, versions = Ext.versions, frameworkVer = versions.ext || versions.touch, i, index, matches, minVer, maxVer, packageName, spec, range, ver; if (!isArray) { checkVerTemp[0] = specs; } for (i = 0; i < length; ++i) { if (!Ext.isString(spec = compat[i])) { matches = Ext.checkVersion(spec.and || spec.or, !spec.or); if (spec.not) { matches = !matches; } } else { if (spec.indexOf(' ') >= 0) { spec = spec.replace(stripRe, ''); } index = spec.indexOf('@'); if (index < 0) { range = spec; ver = frameworkVer; } else { packageName = spec.substring(0, index); if (!(ver = versions[aliases[packageName] || packageName])) { if (matchAll) { return false; } continue; } range = spec.substring(index + 1); } index = range.indexOf('-'); if (index < 0) { if (range.charAt(index = range.length - 1) === '+') { minVer = range.substring(0, index); maxVer = null; } else { minVer = maxVer = range; } } else if (index > 0) { minVer = range.substring(0, index); maxVer = range.substring(index + 1); } else { minVer = null; maxVer = range.substring(index + 1); } matches = true; if (minVer) { minVer = new Version(minVer, '~'); matches = minVer.ltEq(ver); } if (matches && maxVer) { maxVer = new Version(maxVer, '~'); matches = maxVer.gtEq(ver); } } if (matches) { if (!matchAll) { return true; } } else if (matchAll) { return false; } } return !!matchAll; }, deprecate: function(packageName, since, closure, scope) { if (Version.compare(Ext.getVersion(packageName), since) < 1) { closure.call(scope); } } }); }()); (function(manifest) { var packages = (manifest && manifest.packages) || {}, compat = manifest && manifest.compatibility, name, pkg; for (name in packages) { pkg = packages[name]; Ext.setVersion(name, pkg.version); } if (compat) { if (Ext.isString(compat)) { Ext.setCompatVersion('core', compat); } else { for (name in compat) { Ext.setCompatVersion(name, compat[name]); } } } if (!packages.ext && !packages.touch) { Ext.setVersion('ext','5.1.1.451');Ext.setVersion('sencha-core','5.1.1.451'); } })(Ext.manifest); Ext.Config = function(name) { var me = this, capitalizedName = name.charAt(0).toUpperCase() + name.substr(1); me.name = name; me.names = { internal: '_' + name, initializing: 'is' + capitalizedName + 'Initializing', apply: 'apply' + capitalizedName, update: 'update' + capitalizedName, get: 'get' + capitalizedName, set: 'set' + capitalizedName, initGet: 'initGet' + capitalizedName, doSet: 'doSet' + capitalizedName, changeEvent: name.toLowerCase() + 'change' }; me.root = me; }; Ext.Config.map = {}; Ext.Config.get = function(name) { var map = Ext.Config.map, ret = map[name] || (map[name] = new Ext.Config(name)); return ret; }; Ext.Config.prototype = { self: Ext.Config, isConfig: true, getGetter: function() { return this.getter || (this.root.getter = this.makeGetter()); }, getInitGetter: function() { return this.initGetter || (this.root.initGetter = this.makeInitGetter()); }, getSetter: function() { return this.setter || (this.root.setter = this.makeSetter()); }, getInternalName: function(target) { return target.$configPrefixed ? this.names.internal : this.name; }, mergeNew: function(newValue, oldValue, target, mixinClass) { var ret, key; if (!oldValue) { ret = newValue; } else if (!newValue) { ret = oldValue; } else { ret = Ext.Object.chain(oldValue); for (key in newValue) { if (!mixinClass || !(key in ret)) { ret[key] = newValue[key]; } } } return ret; }, mergeSets: function(newValue, oldValue, preserveExisting) { var ret = oldValue ? Ext.Object.chain(oldValue) : {}, i, val; if (newValue instanceof Array) { for (i = newValue.length; i--; ) { val = newValue[i]; if (!preserveExisting || !(val in ret)) { ret[val] = true; } } } else if (newValue) { if (newValue.constructor === Object) { for (i in newValue) { val = newValue[i]; if (!preserveExisting || !(i in ret)) { ret[i] = val; } } } else if (!preserveExisting || !(newValue in ret)) { ret[newValue] = true; } } return ret; }, makeGetter: function() { var name = this.name, prefixedName = this.names.internal; return function() { var internalName = this.$configPrefixed ? prefixedName : name; return this[internalName]; }; }, makeInitGetter: function() { var name = this.name, names = this.names, setName = names.set, getName = names.get, initializingName = names.initializing; return function() { var me = this; me[initializingName] = true; delete me[getName]; me[setName](me.config[name]); delete me[initializingName]; return me[getName].apply(me, arguments); }; }, makeSetter: function() { var name = this.name, names = this.names, prefixedName = names.internal, getName = names.get, applyName = names.apply, updateName = names.update, setter; setter = function(value) { var me = this, internalName = me.$configPrefixed ? prefixedName : name, oldValue = me[internalName]; delete me[getName]; if (!me[applyName] || (value = me[applyName](value, oldValue)) !== undefined) { if (value !== (oldValue = me[internalName])) { me[internalName] = value; if (me[updateName]) { me[updateName](value, oldValue); } } } return me; }; setter.$isDefault = true; return setter; } }; (function() { var ExtConfig = Ext.Config, configPropMap = ExtConfig.map, ExtObject = Ext.Object; Ext.Configurator = function(cls) { var me = this, prototype = cls.prototype, zuper = cls.superclass ? cls.superclass.self.$config : null; me.cls = cls; if (zuper) { me.configs = ExtObject.chain(zuper.configs); me.cachedConfigs = ExtObject.chain(zuper.cachedConfigs); me.initMap = ExtObject.chain(zuper.initMap); me.values = ExtObject.chain(zuper.values); me.needsFork = zuper.needsFork; } else { me.configs = {}; me.cachedConfigs = {}; me.initMap = {}; me.values = {}; } prototype.config = prototype.defaultConfig = me.values; cls.$config = me; }; Ext.Configurator.prototype = { self: Ext.Configurator, needsFork: false, initList: null, add: function(config, mixinClass) { var me = this, Cls = me.cls, configs = me.configs, cachedConfigs = me.cachedConfigs, initMap = me.initMap, prototype = Cls.prototype, mixinConfigs = mixinClass && mixinClass.$config.configs, values = me.values, isObject, meta, isCached, merge, cfg, currentValue, name, names, s, value; for (name in config) { value = config[name]; isObject = value && value.constructor === Object; meta = isObject && '$value' in value ? value : null; if (meta) { isCached = !!meta.cached; value = meta.$value; isObject = value && value.constructor === Object; } merge = meta && meta.merge; cfg = configs[name]; if (cfg) { if (mixinClass) { merge = cfg.merge; if (!merge) { continue; } meta = null; } else { merge = merge || cfg.merge; } if (!mixinClass && isCached && !cachedConfigs[name]) { Ext.Error.raise('Redefining config as cached: ' + name + ' in class: ' + Cls.$className); } currentValue = values[name]; if (merge) { value = merge.call(cfg, value, currentValue, Cls, mixinClass); } else if (isObject) { if (currentValue && currentValue.constructor === Object) { value = ExtObject.merge({}, currentValue, value); } } } else { if (mixinConfigs) { cfg = mixinConfigs[name]; meta = null; } else { cfg = ExtConfig.get(name); } configs[name] = cfg; if (cfg.cached || isCached) { cachedConfigs[name] = true; } names = cfg.names; if (!prototype[s = names.get]) { prototype[s] = cfg.getGetter(); } if (!prototype[s = names.set]) { prototype[s] = cfg.getSetter(); } } if (meta) { if (cfg.owner !== Cls) { configs[name] = cfg = Ext.Object.chain(cfg); cfg.owner = Cls; } Ext.apply(cfg, meta); delete cfg.$value; } if (!me.needsFork && value && (value.constructor === Object || value instanceof Array)) { me.needsFork = true; } if (value !== null) { initMap[name] = true; } else { if (prototype.$configPrefixed) { prototype[configs[name].names.internal] = null; } else { prototype[configs[name].name] = null; } if (name in initMap) { initMap[name] = false; } } values[name] = value; } }, configure: function(instance, instanceConfig) { var me = this, configs = me.configs, initMap = me.initMap, initListMap = me.initListMap, initList = me.initList, prototype = me.cls.prototype, values = me.values, remaining = 0, firstInstance = !initList, cachedInitList, cfg, getter, needsInit, i, internalName, ln, names, name, value, isCached, valuesKey; values = me.needsFork ? ExtObject.fork(values) : ExtObject.chain(values); if (firstInstance) { me.initList = initList = []; me.initListMap = initListMap = {}; instance.isFirstInstance = true; for (name in initMap) { needsInit = initMap[name]; cfg = configs[name]; isCached = cfg.cached; if (needsInit) { names = cfg.names; value = values[name]; if (!prototype[names.set].$isDefault || prototype[names.apply] || prototype[names.update] || typeof value === 'object') { if (isCached) { (cachedInitList || (cachedInitList = [])).push(cfg); } else { initList.push(cfg); initListMap[name] = true; } instance[names.get] = cfg.initGetter || cfg.getInitGetter(); } else { prototype[cfg.getInternalName(prototype)] = value; } } else if (isCached) { prototype[cfg.getInternalName(prototype)] = undefined; } } } ln = cachedInitList && cachedInitList.length; if (ln) { for (i = 0; i < ln; ++i) { internalName = cachedInitList[i].getInternalName(prototype); instance[internalName] = null; } for (i = 0; i < ln; ++i) { names = (cfg = cachedInitList[i]).names; getter = names.get; if (instance.hasOwnProperty(getter)) { instance[names.set](values[cfg.name]); delete instance[getter]; } } for (i = 0; i < ln; ++i) { internalName = cachedInitList[i].getInternalName(prototype); prototype[internalName] = instance[internalName]; delete instance[internalName]; } } if (instanceConfig && instanceConfig.platformConfig) { instanceConfig = me.resolvePlatformConfig(instance, instanceConfig); } if (firstInstance) { if (instance.afterCachedConfig && !instance.afterCachedConfig.$nullFn) { instance.afterCachedConfig(instanceConfig); } } instance.isConfiguring = true; instance.config = values; for (i = 0 , ln = initList.length; i < ln; ++i) { cfg = initList[i]; instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter(); } if (instance.transformInstanceConfig) { instanceConfig = instance.transformInstanceConfig(instanceConfig); } if (instanceConfig) { for (name in instanceConfig) { value = instanceConfig[name]; cfg = configs[name]; if (!cfg) { if (instance.$configStrict && typeof instance.self.prototype[name] === 'function') { Ext.Error.raise("Cannot override method " + name + " on " + instance.$className + " instance."); } instance[name] = value; } else { if (!cfg.lazy) { ++remaining; } if (!initListMap[name]) { instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter(); } if (cfg.merge) { value = cfg.merge(value, values[name], instance); } else if (value && value.constructor === Object) { valuesKey = values[name]; if (valuesKey && valuesKey.constructor === Object) { value = ExtObject.merge(values[name], value); } else { value = Ext.clone(value); } } } values[name] = value; } } if (instance.beforeInitConfig && !instance.beforeInitConfig.$nullFn) { if (instance.beforeInitConfig(instanceConfig) === false) { return; } } if (instanceConfig) { for (name in instanceConfig) { if (!remaining) { break; } cfg = configs[name]; if (cfg && !cfg.lazy) { --remaining; names = cfg.names; getter = names.get; if (instance.hasOwnProperty(getter)) { instance[names.set](values[name]); delete instance[names.get]; } } } } for (i = 0 , ln = initList.length; i < ln; ++i) { cfg = initList[i]; names = cfg.names; getter = names.get; if (!cfg.lazy && instance.hasOwnProperty(getter)) { instance[names.set](values[cfg.name]); delete instance[getter]; } } delete instance.isConfiguring; }, getCurrentConfig: function(instance) { var defaultConfig = instance.defaultConfig, config = {}, name; for (name in defaultConfig) { config[name] = instance[configPropMap[name].names.get](); } return config; }, merge: function(instance, baseConfig, config) { var configs = this.configs, name, value, baseValue, cfg; for (name in config) { value = config[name]; cfg = configs[name]; if (cfg) { if (cfg.merge) { value = cfg.merge(value, baseConfig[name], instance); } else if (value && value.constructor === Object) { baseValue = baseConfig[name]; if (baseValue && baseValue.constructor === Object) { value = Ext.Object.merge(baseValue, value); } else { value = Ext.clone(value); } } } baseConfig[name] = value; } return baseConfig; }, reconfigure: function(instance, instanceConfig, options) { var currentConfig = instance.config, configList = [], strict = instance.$configStrict, configs = this.configs, defaults = options && options.defaults, applyProps = options && options.strict === false, cfg, getter, i, len, name, names, setter; for (name in instanceConfig) { if (defaults && instance.hasOwnProperty(name)) { continue; } currentConfig[name] = instanceConfig[name]; cfg = configs[name]; if (cfg) { instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter(); } else if (strict) { if (name !== 'type') { Ext.log.error('No such config "' + name + '" for class ' + instance.$className); } continue; } configList.push(name); } for (i = 0 , len = configList.length; i < len; i++) { name = configList[i]; cfg = configs[name]; if (cfg) { names = cfg.names; getter = names.get; if (instance.hasOwnProperty(getter)) { instance[names.set](instanceConfig[name]); delete instance[getter]; } } else { cfg = configPropMap[name] || Ext.Config.get(name); names = cfg.names; if (instance[names.set]) { instance[names.set](instanceConfig[name]); } else if (applyProps) { if (instance.$configStrict && typeof instance.self.prototype[name] === 'function') { Ext.Error.raise("Cannot override method " + name + " on " + instance.$className + " instance."); } instance[name] = instanceConfig[name]; } else if (name !== 'type') { Ext.Error.raise('Config "' + name + '" has no setter on class ' + instance.$className); } } } }, resolvePlatformConfig: function(instance, instanceConfig) { var platformConfig = instanceConfig && instanceConfig.platformConfig, ret = instanceConfig, i, keys, n; if (platformConfig) { keys = Ext.getPlatformConfigKeys(platformConfig); n = keys.length; if (n) { ret = Ext.merge({}, ret); for (i = 0 , n = keys.length; i < n; ++i) { this.merge(instance, ret, platformConfig[keys[i]]); } } } return ret; } }; }()); Ext.Base = (function(flexSetter) { var noArgs = [], baseStaticMember, baseStaticMembers = [], getConfig = function(name, peek) { var me = this, ret, cfg, getterName; if (name) { cfg = Ext.Config.map[name]; if (!cfg) { Ext.Logger.error("Invalid property name for getter: '" + name + "' for '" + me.$className + "'."); } getterName = cfg.names.get; if (peek && me.hasOwnProperty(getterName)) { ret = me.config[name]; } else { ret = me[getterName](); } } else { ret = me.getCurrentConfig(); } return ret; }, makeDeprecatedMethod = function(oldName, newName, msg) { var message = '"' + oldName + '" is deprecated.'; if (msg) { message += ' ' + msg; } else if (newName) { message += ' Please use "' + newName + '" instead.'; } return function() { Ext.Error.raise(message); }; }, addDeprecatedProperty = function(object, oldName, newName, message) { if (!message) { message = '"' + oldName + '" is deprecated.'; } if (newName) { message += ' Please use "' + newName + '" instead.'; } if (message) { Ext.Object.defineProperty(object, oldName, { get: function() { Ext.Error.raise(message); }, set: function(value) { Ext.Error.raise(message); }, configurable: true }); } }, makeAliasFn = function(name) { return function() { return this[name].apply(this, arguments); }; }, Version = Ext.Version, leadingDigitRe = /^\d/, oneMember = {}, aliasOneMember = {}, Base = function() {}, BasePrototype = Base.prototype; Ext.apply(Base, { $className: 'Ext.Base', $isClass: true, create: function() { return Ext.create.apply(Ext, [ this ].concat(Array.prototype.slice.call(arguments, 0))); }, addDeprecations: function(deprecations) { var me = this, all = [], compatVersion = Ext.getCompatVersion(deprecations.name), displayName = (me.$className || '') + '#', deprecate, versionSpec, index, message, target, enabled, existing, fn, names, oldName, newName, member, statics, version; for (versionSpec in deprecations) { if (leadingDigitRe.test(versionSpec)) { version = new Ext.Version(versionSpec); version.deprecations = deprecations[versionSpec]; all.push(version); } } all.sort(Version.compare); for (index = all.length; index--; ) { deprecate = (version = all[index]).deprecations; target = me.prototype; statics = deprecate.statics; enabled = compatVersion && compatVersion.lt(version); if (!enabled) {} else if (!enabled) { break; } while (deprecate) { names = deprecate.methods; if (names) { for (oldName in names) { member = names[oldName]; fn = null; if (!member) { Ext.Assert.isNotDefinedProp(target, oldName); fn = makeDeprecatedMethod(displayName + oldName); } else if (Ext.isString(member)) { Ext.Assert.isNotDefinedProp(target, oldName); Ext.Assert.isDefinedProp(target, member); if (enabled) { fn = makeAliasFn(member); } else { fn = makeDeprecatedMethod(displayName + oldName, member); } } else { message = ''; if (member.message || member.fn) { message = member.message; member = member.fn; } existing = target.hasOwnProperty(oldName) && target[oldName]; if (enabled && member) { member.$owner = me; member.$name = oldName; member.name = displayName + oldName; if (existing) { member.$previous = existing; } fn = member; } else if (!existing) { fn = makeDeprecatedMethod(displayName + oldName, null, message); } } if (fn) { target[oldName] = fn; } } } names = deprecate.properties; if (names && !enabled) { for (oldName in names) { newName = names[oldName]; if (Ext.isString(newName)) { addDeprecatedProperty(target, displayName + oldName, newName); } else if (newName && newName.message) { addDeprecatedProperty(target, displayName + oldName, null, newName.message); } else { addDeprecatedProperty(target, displayName + oldName); } } } deprecate = statics; statics = null; target = me; } } }, extend: function(parent) { var me = this, parentPrototype = parent.prototype, prototype, i, ln, name, statics; prototype = me.prototype = Ext.Object.chain(parentPrototype); prototype.self = me; me.superclass = prototype.superclass = parentPrototype; if (!parent.$isClass) { for (i in BasePrototype) { if (i in prototype) { prototype[i] = BasePrototype[i]; } } } statics = parentPrototype.$inheritableStatics; if (statics) { for (i = 0 , ln = statics.length; i < ln; i++) { name = statics[i]; if (!me.hasOwnProperty(name)) { me[name] = parent[name]; } } } if (parent.$onExtended) { me.$onExtended = parent.$onExtended.slice(); } me.getConfigurator(); }, $onExtended: [], triggerExtended: function() { Ext.classSystemMonitor && Ext.classSystemMonitor(this, 'Ext.Base#triggerExtended', arguments); var callbacks = this.$onExtended, ln = callbacks.length, i, callback; if (ln > 0) { for (i = 0; i < ln; i++) { callback = callbacks[i]; callback.fn.apply(callback.scope || this, arguments); } } }, onExtended: function(fn, scope) { this.$onExtended.push({ fn: fn, scope: scope }); return this; }, addStatics: function(members) { this.addMembers(members, true); return this; }, addInheritableStatics: function(members) { var inheritableStatics, hasInheritableStatics, prototype = this.prototype, name, member; inheritableStatics = prototype.$inheritableStatics; hasInheritableStatics = prototype.$hasInheritableStatics; if (!inheritableStatics) { inheritableStatics = prototype.$inheritableStatics = []; hasInheritableStatics = prototype.$hasInheritableStatics = {}; } var className = Ext.getClassName(this) + '.'; for (name in members) { if (members.hasOwnProperty(name)) { member = members[name]; if (typeof member == 'function') { member.name = className + name; } this[name] = member; if (!hasInheritableStatics[name]) { hasInheritableStatics[name] = true; inheritableStatics.push(name); } } } return this; }, addMembers: function(members, isStatic, privacy) { var me = this, cloneFunction = Ext.Function.clone, target = isStatic ? me : me.prototype, defaultConfig = !isStatic && target.defaultConfig, enumerables = Ext.enumerables, privates = members.privates, configs, i, ln, member, name, subPrivacy, privateStatics; var displayName = (me.$className || '') + '#'; if (privates) { delete members.privates; if (!isStatic) { privateStatics = privates.statics; delete privates.statics; } subPrivacy = privates.privacy || privacy || 'framework'; me.addMembers(privates, isStatic, subPrivacy); if (privateStatics) { me.addMembers(privateStatics, true, subPrivacy); } } for (name in members) { if (members.hasOwnProperty(name)) { member = members[name]; if (privacy === true) { privacy = 'framework'; } if (member && member.$nullFn && privacy !== member.$privacy) { Ext.Error.raise('Cannot use stock function for private method ' + (me.$className ? me.$className + '#' : '') + name); } if (typeof member === 'function' && !member.$isClass && !member.$nullFn) { if (member.$owner) { member = cloneFunction(member); } if (target.hasOwnProperty(name)) { member.$previous = target[name]; } member.$owner = me; member.$name = name; member.name = displayName + name; var existing = target[name]; if (privacy) { member.$privacy = privacy; if (existing && existing.$privacy && existing.$privacy !== privacy) { Ext.privacyViolation(me, existing, member, isStatic); } } else if (existing && existing.$privacy) { Ext.privacyViolation(me, existing, member, isStatic); } } else if (defaultConfig && (name in defaultConfig) && !target.config.hasOwnProperty(name)) { (configs || (configs = {}))[name] = member; continue; } target[name] = member; } } if (configs) { me.addConfig(configs); } if (enumerables) { for (i = 0 , ln = enumerables.length; i < ln; ++i) { if (members.hasOwnProperty(name = enumerables[i])) { member = members[name]; if (member && !member.$nullFn) { if (member.$owner) { member = cloneFunction(member); } member.$owner = me; member.$name = name; member.name = displayName + name; if (target.hasOwnProperty(name)) { member.$previous = target[name]; } } target[name] = member; } } } return this; }, addMember: function(name, member) { oneMember[name] = member; this.addMembers(oneMember); delete oneMember[name]; return this; }, borrow: function(fromClass, members) { Ext.classSystemMonitor && Ext.classSystemMonitor(this, 'Ext.Base#borrow', arguments); var prototype = fromClass.prototype, membersObj = {}, i, ln, name; members = Ext.Array.from(members); for (i = 0 , ln = members.length; i < ln; i++) { name = members[i]; membersObj[name] = prototype[name]; } return this.addMembers(membersObj); }, override: function(members) { var me = this, statics = members.statics, inheritableStatics = members.inheritableStatics, config = members.config, mixins = members.mixins, cachedConfig = members.cachedConfig; if (statics || inheritableStatics || config) { members = Ext.apply({}, members); } if (statics) { me.addMembers(statics, true); delete members.statics; } if (inheritableStatics) { me.addInheritableStatics(inheritableStatics); delete members.inheritableStatics; } if (config) { me.addConfig(config); delete members.config; } if (cachedConfig) { me.addCachedConfig(cachedConfig); delete members.cachedConfig; } delete members.mixins; me.addMembers(members); if (mixins) { me.mixin(mixins); } return me; }, callParent: function(args) { var method; return (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass.self[method.$name])).apply(this, args || noArgs); }, callSuper: function(args) { var method; return (method = this.callSuper.caller) && ((method = method.$owner ? method : method.caller) && method.$owner.superclass.self[method.$name]).apply(this, args || noArgs); }, mixin: function(name, mixinClass) { var me = this, mixin, prototype, key, statics, i, ln, staticName, mixinValue, mixins; if (typeof name !== 'string') { mixins = name; if (mixins instanceof Array) { for (i = 0 , ln = mixins.length; i < ln; i++) { mixin = mixins[i]; me.mixin(mixin.prototype.mixinId || mixin.$className, mixin); } } else { for (var mixinName in mixins) { me.mixin(mixinName, mixins[mixinName]); } } return; } mixin = mixinClass.prototype; prototype = me.prototype; if (mixin.onClassMixedIn) { mixin.onClassMixedIn.call(mixinClass, me); } if (!prototype.hasOwnProperty('mixins')) { if ('mixins' in prototype) { prototype.mixins = Ext.Object.chain(prototype.mixins); } else { prototype.mixins = {}; } } for (key in mixin) { mixinValue = mixin[key]; if (key === 'mixins') { Ext.applyIf(prototype.mixins, mixinValue); } else if (!(key === 'mixinId' || key === 'config') && (prototype[key] === undefined)) { prototype[key] = mixinValue; } } statics = mixin.$inheritableStatics; if (statics) { for (i = 0 , ln = statics.length; i < ln; i++) { staticName = statics[i]; if (!me.hasOwnProperty(staticName)) { me[staticName] = mixinClass[staticName]; } } } if ('config' in mixin) { me.addConfig(mixin.config, mixinClass); } prototype.mixins[name] = mixin; if (mixin.afterClassMixedIn) { mixin.afterClassMixedIn.call(mixinClass, me); } return me; }, addConfig: function(config, mixinClass) { var cfg = this.$config || this.getConfigurator(); cfg.add(config, mixinClass); }, addCachedConfig: function(config, isMixin) { var cached = {}, key; for (key in config) { cached[key] = { cached: true, $value: config[key] }; } this.addConfig(cached, isMixin); }, getConfigurator: function() { return this.$config || new Ext.Configurator(this); }, getName: function() { return Ext.getClassName(this); }, createAlias: flexSetter(function(alias, origin) { aliasOneMember[alias] = function() { return this[origin].apply(this, arguments); }; this.override(aliasOneMember); delete aliasOneMember[alias]; }) }); for (baseStaticMember in Base) { if (Base.hasOwnProperty(baseStaticMember)) { baseStaticMembers.push(baseStaticMember); } } Base.$staticMembers = baseStaticMembers; Base.getConfigurator(); Base.addMembers({ $className: 'Ext.Base', isInstance: true, $configPrefixed: true, $configStrict: true, isConfiguring: false, isFirstInstance: false, statics: function() { var method = this.statics.caller, self = this.self; if (!method) { return self; } return method.$owner; }, callParent: function(args) { var method, superMethod = (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name])); if (!superMethod) { method = this.callParent.caller; var parentClass, methodName; if (!method.$owner) { if (!method.caller) { throw new Error("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)) { throw new Error("this.callParent() was called but there's no such method (" + methodName + ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")"); } } return superMethod.apply(this, args || noArgs); }, callSuper: function(args) { var method, superMethod = (method = this.callSuper.caller) && ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name]); if (!superMethod) { method = this.callSuper.caller; var parentClass, methodName; if (!method.$owner) { if (!method.caller) { throw new Error("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)) { throw new Error("this.callSuper() was called but there's no such method (" + methodName + ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")"); } } return superMethod.apply(this, args || noArgs); }, self: Base, constructor: function() { return this; }, getConfigurator: function() { return this.$config || this.self.getConfigurator(); }, initConfig: function(instanceConfig) { var me = this, cfg = me.getConfigurator(); me.initConfig = Ext.emptyFn; me.initialConfig = instanceConfig || {}; cfg.configure(me, instanceConfig); return me; }, beforeInitConfig: Ext.emptyFn, getConfig: getConfig, setConfig: function(name, value, options) { var me = this, config; if (name) { if (typeof name === 'string') { config = {}; config[name] = value; } else { config = name; } me.getConfigurator().reconfigure(me, config, options); } return me; }, getCurrentConfig: function() { var cfg = this.getConfigurator(); return cfg.getCurrentConfig(this); }, hasConfig: function(name) { return name in this.defaultConfig; }, getInitialConfig: function(name) { var config = this.config; if (!name) { return config; } return config[name]; }, $links: null, link: function(name, value) { var me = this, links = me.$links || (me.$links = {}); links[name] = true; me[name] = value; return value; }, unlink: function(names) { var me = this, i, ln, link, value; if (!Ext.isArray(names)) { Ext.Error.raise('Invalid argument - expected array of strings'); } for (i = 0 , ln = names.length; i < ln; i++) { link = names[i]; value = me[link]; if (value) { if (value.isInstance && !value.isDestroyed) { value.destroy(); } else if (value.parentNode && 'nodeType' in value) { value.parentNode.removeChild(value); } } me[link] = null; } return me; }, destroy: function() { var me = this, links = me.$links; me.destroy = Ext.emptyFn; me.isDestroyed = true; if (links) { me.$links = null; me.unlink(Ext.Object.getKeys(links)); } } }); BasePrototype.callOverridden = BasePrototype.callParent; Ext.privacyViolation = function(cls, existing, member, isStatic) { var name = member.$name, conflictCls = existing.$owner && existing.$owner.$className, s = isStatic ? 'static ' : '', msg = member.$privacy ? 'Private ' + s + member.$privacy + ' method "' + name + '"' : 'Public ' + s + 'method "' + name + '"'; if (cls.$className) { msg = cls.$className + ': ' + msg; } if (!existing.$privacy) { msg += conflictCls ? ' hides public method inherited from ' + conflictCls : ' hides inherited public method.'; } else { msg += conflictCls ? ' conflicts with private ' + existing.$privacy + ' method declared by ' + conflictCls : ' conflicts with inherited private ' + existing.$privacy + ' method.'; } var compat = Ext.getCompatVersion(); var ver = Ext.getVersion(); if (ver && compat && compat.lt(ver)) { Ext.log.error(msg); } else { Ext.Error.raise(msg); } }; return Base; }(Ext.Function.flexSetter)); (function(Cache, prototype) { (Ext.util || (Ext.util = {})).Cache = Cache = function(config) { var me = this, head; if (config) { Ext.apply(me, config); } me.head = head = { id: (me.seed = 0), key: null, value: null }; me.map = {}; head.next = head.prev = head; }; Cache.prototype = prototype = { maxSize: 100, count: 0, clear: function() { var me = this, head = me.head, entry = head.next; head.next = head.prev = head; if (!me.evict.$nullFn) { for (; entry !== head; entry = entry.next) { me.evict(entry.key, entry.value); } } me.count = 0; }, each: function(fn, scope) { scope = scope || this; for (var head = this.head, ent = head.next; ent !== head; ent = ent.next) { if (fn.call(scope, ent.key, ent.value)) { break; } } }, get: function(key) { var me = this, head = me.head, map = me.map, entry = map[key]; if (entry) { if (entry.prev !== head) { me.unlinkEntry(entry); me.linkEntry(entry); } } else { map[key] = entry = { id: ++me.seed, key: key, value: me.miss.apply(me, arguments) }; me.linkEntry(entry); ++me.count; while (me.count > me.maxSize) { me.unlinkEntry(head.prev, true); --me.count; } } return entry.value; }, evict: Ext.emptyFn, linkEntry: function(entry) { var head = this.head, first = head.next; entry.next = first; entry.prev = head; head.next = entry; first.prev = entry; }, unlinkEntry: function(entry, evicted) { var next = entry.next, prev = entry.prev; prev.next = next; next.prev = prev; if (evicted) { this.evict(entry.key, entry.value); } } }; prototype.destroy = prototype.clear; }()); (function() { var ExtClass, Base = Ext.Base, baseStaticMembers = Base.$staticMembers, ruleKeySortFn = function(a, b) { return (a.length - b.length) || ((a < b) ? -1 : ((a > b) ? 1 : 0)); }; function makeCtor(className) { function constructor() { return this.constructor.apply(this, arguments) || null; } if (className) { constructor.name = className; } return constructor; } Ext.Class = ExtClass = function(Class, data, onCreated) { if (typeof Class != 'function') { onCreated = data; data = Class; Class = null; } if (!data) { data = {}; } Class = ExtClass.create(Class, data); ExtClass.process(Class, data, onCreated); return Class; }; Ext.apply(ExtClass, { makeCtor: makeCtor, onBeforeCreated: function(Class, data, hooks) { Ext.classSystemMonitor && Ext.classSystemMonitor(Class, '>> Ext.Class#onBeforeCreated', arguments); Class.addMembers(data); hooks.onCreated.call(Class, Class); Ext.classSystemMonitor && Ext.classSystemMonitor(Class, '<< Ext.Class#onBeforeCreated', arguments); }, create: function(Class, data) { var i = baseStaticMembers.length, name; if (!Class) { Class = makeCtor(data.$className); } while (i--) { name = baseStaticMembers[i]; Class[name] = Base[name]; } return Class; }, process: function(Class, data, onCreated) { var preprocessorStack = data.preprocessors || ExtClass.defaultPreprocessors, registeredPreprocessors = this.preprocessors, hooks = { onBeforeCreated: this.onBeforeCreated }, preprocessors = [], preprocessor, preprocessorsProperties, i, ln, j, subLn, preprocessorProperty; delete data.preprocessors; Class._classHooks = hooks; for (i = 0 , ln = preprocessorStack.length; i < ln; i++) { preprocessor = preprocessorStack[i]; if (typeof preprocessor == 'string') { preprocessor = registeredPreprocessors[preprocessor]; preprocessorsProperties = preprocessor.properties; if (preprocessorsProperties === true) { preprocessors.push(preprocessor.fn); } else if (preprocessorsProperties) { for (j = 0 , subLn = preprocessorsProperties.length; j < subLn; j++) { preprocessorProperty = preprocessorsProperties[j]; if (data.hasOwnProperty(preprocessorProperty)) { preprocessors.push(preprocessor.fn); break; } } } } else { preprocessors.push(preprocessor); } } hooks.onCreated = onCreated ? onCreated : Ext.emptyFn; hooks.preprocessors = preprocessors; this.doProcess(Class, data, hooks); }, doProcess: function(Class, data, hooks) { var me = this, preprocessors = hooks.preprocessors, preprocessor = preprocessors.shift(), doProcess = me.doProcess; for (; preprocessor; preprocessor = preprocessors.shift()) { if (preprocessor.call(me, Class, data, hooks, doProcess) === false) { return; } } hooks.onBeforeCreated.apply(me, arguments); }, preprocessors: {}, registerPreprocessor: function(name, fn, properties, position, relativeTo) { if (!position) { position = 'last'; } if (!properties) { properties = [ name ]; } this.preprocessors[name] = { name: name, properties: properties || false, fn: fn }; this.setDefaultPreprocessorPosition(name, position, relativeTo); return this; }, getPreprocessor: function(name) { return this.preprocessors[name]; }, getPreprocessors: function() { return this.preprocessors; }, defaultPreprocessors: [], 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) { Ext.Array.splice(defaultPreprocessors, Math.max(0, index + offset), 0, name); } return this; } }); ExtClass.registerPreprocessor('extend', function(Class, data, hooks) { Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#extendPreProcessor', arguments); var Base = Ext.Base, basePrototype = Base.prototype, extend = data.extend, Parent, parentPrototype, i; delete data.extend; if (extend && extend !== Object) { Parent = extend; } else { Parent = Base; } parentPrototype = Parent.prototype; if (!Parent.$isClass) { for (i in basePrototype) { if (!parentPrototype[i]) { parentPrototype[i] = basePrototype[i]; } } } Class.extend(Parent); Class.triggerExtended.apply(Class, arguments); if (data.onClassExtended) { Class.onExtended(data.onClassExtended, Class); delete data.onClassExtended; } }, true); ExtClass.registerPreprocessor('privates', function(Class, data) { Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#privatePreprocessor', arguments); var privates = data.privates, statics = privates.statics, privacy = privates.privacy || true; delete data.privates; delete privates.statics; Class.addMembers(privates, false, privacy); if (statics) { Class.addMembers(statics, true, privacy); } }); ExtClass.registerPreprocessor('statics', function(Class, data) { Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#staticsPreprocessor', arguments); Class.addStatics(data.statics); delete data.statics; }); ExtClass.registerPreprocessor('inheritableStatics', function(Class, data) { Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#inheritableStaticsPreprocessor', arguments); Class.addInheritableStatics(data.inheritableStatics); delete data.inheritableStatics; }); Ext.createRuleFn = function(code) { return new Function('$c', 'with($c) { return (' + code + '); }'); }; Ext.expressionCache = new Ext.util.Cache({ miss: Ext.createRuleFn }); Ext.ruleKeySortFn = ruleKeySortFn; Ext.getPlatformConfigKeys = function(platformConfig) { var ret = [], platform, rule; for (platform in platformConfig) { rule = Ext.expressionCache.get(platform); if (rule(Ext.platformTags)) { ret.push(platform); } } ret.sort(ruleKeySortFn); return ret; }; ExtClass.registerPreprocessor('platformConfig', function(Class, data, hooks) { var platformConfigs = data.platformConfig, config = data.config, added, classConfigs, configs, configurator, hoisted, keys, name, value, platform, theme, platformConfig, i, ln, j, ln2, themeName; delete data.platformConfig; if (platformConfigs instanceof Array) { config = config || {}; themeName = (Ext.theme || (Ext.theme = { name: 'Default' })).name; for (i = 0 , ln = platformConfigs.length; i < ln; i++) { platformConfig = platformConfigs[i]; platform = platformConfig.platform; delete platformConfig.platform; theme = [].concat(platformConfig.theme); ln2 = theme.length; delete platformConfig.theme; if (platform && Ext.filterPlatform(platform)) { Ext.merge(config, platformConfig); } if (ln2) { for (j = 0; j < ln2; j++) { if (themeName === theme[j]) { Ext.merge(config, platformConfig); } } } } } else { configurator = Class.getConfigurator(); classConfigs = configurator.configs; keys = Ext.getPlatformConfigKeys(platformConfigs); for (i = 0 , ln = keys.length; i < ln; ++i) { configs = platformConfigs[keys[i]]; hoisted = added = null; for (name in configs) { value = configs[name]; if (config && name in config) { (added || (added = {}))[name] = value; (hoisted || (hoisted = {}))[name] = config[name]; delete config[name]; } else if (name in classConfigs) { (added || (added = {}))[name] = value; } else { data[name] = value; } } if (hoisted) { configurator.add(hoisted); } if (added) { configurator.add(added); } } } }); ExtClass.registerPreprocessor('config', function(Class, data) { if (data.hasOwnProperty('$configPrefixed')) { Class.prototype.$configPrefixed = data.$configPrefixed; } Class.addConfig(data.config); delete data.config; }); ExtClass.registerPreprocessor('cachedConfig', function(Class, data) { if (data.hasOwnProperty('$configPrefixed')) { Class.prototype.$configPrefixed = data.$configPrefixed; } Class.addCachedConfig(data.cachedConfig); delete data.cachedConfig; }); ExtClass.registerPreprocessor('mixins', function(Class, data, hooks) { Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#mixinsPreprocessor', arguments); var mixins = data.mixins, onCreated = hooks.onCreated; delete data.mixins; hooks.onCreated = function() { Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#mixinsPreprocessor#beforeCreated', arguments); hooks.onCreated = onCreated; Class.mixin(mixins); return hooks.onCreated.apply(this, arguments); }; }); Ext.extend = function(Class, Parent, members) { Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#extend-backwards-compatible', arguments); if (arguments.length === 2 && Ext.isObject(Parent)) { members = Parent; Parent = Class; Class = null; } var cls; if (!Parent) { throw new Error("[Ext.extend] Attempting to extend from a class which has not been loaded on the page."); } members.extend = Parent; members.preprocessors = [ 'extend', 'statics', 'inheritableStatics', 'mixins', 'platformConfig', 'config' ]; if (Class) { cls = new ExtClass(Class, members); cls.prototype.constructor = Class; } else { cls = new ExtClass(members); } cls.prototype.override = function(o) { for (var m in o) { if (o.hasOwnProperty(m)) { this[m] = o[m]; } } }; return cls; }; }()); Ext.Inventory = function() { var me = this; me.names = []; me.paths = {}; me.alternateToName = {}; me.aliasToName = {}; me.nameToAliases = {}; me.nameToAlternates = {}; }; Ext.Inventory.prototype = { _array1: [ 0 ], prefixes: null, dotRe: /\./g, wildcardRe: /\*/g, addAlias: function(className, alias) { return this.addMapping(className, alias, this.aliasToName, this.nameToAliases); }, addAlternate: function(className, alternate) { return this.addMapping(className, alternate, this.alternateToName, this.nameToAlternates); }, addMapping: function(className, alternate, toName, nameTo) { var name = className.$className || className, mappings = name, array = this._array1, a, aliases, cls, i, length, nameMapping; if (Ext.isString(name)) { mappings = {}; mappings[name] = alternate; } for (cls in mappings) { aliases = mappings[cls]; if (Ext.isString(aliases)) { array[0] = aliases; aliases = array; } length = aliases.length; nameMapping = nameTo[cls] || (nameTo[cls] = []); for (i = 0; i < length; ++i) { if (!(a = aliases[i])) { continue; } if (toName[a] !== cls) { if (toName[a]) { Ext.log.warn("Overriding existing mapping: '" + a + "' From '" + toName[a] + "' to '" + cls + "'. Is this intentional?"); } toName[a] = cls; nameMapping.push(a); } } } }, getAliasesByName: function(name) { return this.nameToAliases[name] || null; }, getAlternatesByName: function(name) { return this.nameToAlternates[name] || null; }, getNameByAlias: function(alias) { return this.aliasToName[alias] || ''; }, getNameByAlternate: function(alternate) { return this.alternateToName[alternate] || ''; }, getNamesByExpression: function(expression, exclude, accumulate) { var me = this, aliasToName = me.aliasToName, alternateToName = me.alternateToName, nameToAliases = me.nameToAliases, nameToAlternates = me.nameToAlternates, map = accumulate ? exclude : {}, names = [], expressions = Ext.isString(expression) ? [ expression ] : expression, length = expressions.length, wildcardRe = me.wildcardRe, expr, i, list, match, n, name, regex; for (i = 0; i < length; ++i) { if ((expr = expressions[i]).indexOf('*') < 0) { if (!(name = aliasToName[expr])) { if (!(name = alternateToName[expr])) { name = expr; } } if (!(name in map) && !(exclude && (name in exclude))) { map[name] = 1; names.push(name); } } else { regex = new RegExp('^' + expr.replace(wildcardRe, '(.*?)') + '$'); for (name in nameToAliases) { if (!(name in map) && !(exclude && (name in exclude))) { if (!(match = regex.test(name))) { n = (list = nameToAliases[name]).length; while (!match && n-- > 0) { match = regex.test(list[n]); } list = nameToAlternates[name]; if (list && !match) { n = list.length; while (!match && n-- > 0) { match = regex.test(list[n]); } } } if (match) { map[name] = 1; names.push(name); } } } } } return names; }, getPath: function(className) { var me = this, paths = me.paths, ret = '', prefix; if (className in paths) { ret = paths[className]; } else { prefix = me.getPrefix(className); if (prefix) { className = className.substring(prefix.length + 1); ret = paths[prefix]; if (ret) { ret += '/'; } } ret += className.replace(me.dotRe, '/') + '.js'; } return ret; }, getPrefix: function(className) { if (className in this.paths) { return className; } var prefixes = this.getPrefixes(), i = prefixes.length, length, prefix; while (i-- > 0) { length = (prefix = prefixes[i]).length; if (length < className.length && className.charAt(length) === '.' && prefix === className.substring(0, length)) { return prefix; } } return ''; }, getPrefixes: function() { var me = this, prefixes = me.prefixes; if (!prefixes) { me.prefixes = prefixes = me.names.slice(0); prefixes.sort(me._compareNames); } return prefixes; }, removeName: function(name) { var me = this, aliasToName = me.aliasToName, alternateToName = me.alternateToName, nameToAliases = me.nameToAliases, nameToAlternates = me.nameToAlternates, aliases = nameToAliases[name], alternates = nameToAlternates[name], i, a; delete nameToAliases[name]; delete nameToAlternates[name]; if (aliases) { for (i = aliases.length; i--; ) { if (name === (a = aliases[i])) { delete aliasToName[a]; } } } if (alternates) { for (i = alternates.length; i--; ) { if (name === (a = alternates[i])) { delete alternateToName[a]; } } } }, resolveName: function(name) { var me = this, trueName; if (!(name in me.nameToAliases)) { if (!(trueName = me.aliasToName[name])) { trueName = me.alternateToName[name]; } } return trueName || name; }, select: function(receiver, scope) { var me = this, excludes = {}, ret = { excludes: excludes, exclude: function() { me.getNamesByExpression(arguments, excludes, true); return this; } }, name; for (name in receiver) { ret[name] = me.selectMethod(excludes, receiver[name], scope || receiver); } return ret; }, selectMethod: function(excludes, fn, scope) { var me = this; return function(include) { var args = Ext.Array.slice(arguments, 1); args.unshift(me.getNamesByExpression(include, excludes)); return fn.apply(scope, args); }; }, setPath: Ext.Function.flexSetter(function(name, path) { var me = this; me.paths[name] = path; me.names.push(name); me.prefixes = null; return me; }), _compareNames: function(lhs, rhs) { var cmp = lhs.length - rhs.length; if (!cmp) { cmp = (lhs < rhs) ? -1 : 1; } return cmp; } }; Ext.ClassManager = (function(Class, alias, arraySlice, arrayFrom, global) { var makeCtor = Ext.Class.makeCtor, Manager = Ext.apply(new Ext.Inventory(), { classes: {}, classState: {}, existCache: {}, namespaceRewrites: [ { from: 'Ext.', to: Ext } ], enableNamespaceParseCache: true, namespaceParseCache: {}, instantiators: [], isCreated: function(className) { var i, ln, part, root, parts; if (typeof className !== 'string' || className.length < 1) { throw new Error("[Ext.ClassManager] Invalid classname, must be a string and must not be empty"); } if (Manager.classes[className] || Manager.existCache[className]) { return true; } root = global; parts = Manager.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]; } } Manager.triggerCreated(className); return true; }, createdListeners: [], nameCreatedListeners: {}, existsListeners: [], nameExistsListeners: {}, overrideMap: {}, triggerCreated: function(className, state) { Manager.existCache[className] = state || 1; Manager.classState[className] += 40; Manager.notify(className, Manager.createdListeners, Manager.nameCreatedListeners); }, onCreated: function(fn, scope, className) { Manager.addListener(fn, scope, className, Manager.createdListeners, Manager.nameCreatedListeners); }, notify: function(className, listeners, nameListeners) { var alternateNames = Manager.getAlternatesByName(className), names = [ className ], i, ln, j, subLn, listener, name; for (i = 0 , ln = listeners.length; i < ln; i++) { listener = listeners[i]; listener.fn.call(listener.scope, className); } while (names) { for (i = 0 , ln = names.length; i < ln; i++) { name = names[i]; listeners = nameListeners[name]; if (listeners) { for (j = 0 , subLn = listeners.length; j < subLn; j++) { listener = listeners[j]; listener.fn.call(listener.scope, name); } delete nameListeners[name]; } } names = alternateNames; alternateNames = null; } }, addListener: function(fn, scope, className, listeners, nameListeners) { if (Ext.isArray(className)) { fn = Ext.Function.createBarrier(className.length, fn, scope); for (i = 0; i < className.length; i++) { this.addListener(fn, null, className[i], listeners, nameListeners); } return; } var i, listener = { fn: fn, scope: scope }; if (className) { if (this.isCreated(className)) { fn.call(scope, className); return; } if (!nameListeners[className]) { nameListeners[className] = []; } nameListeners[className].push(listener); } else { listeners.push(listener); } }, parseNamespace: function(namespace) { if (typeof namespace !== 'string') { throw new Error("[Ext.ClassManager] Invalid namespace, must be a string"); } var cache = this.namespaceParseCache, parts, rewrites, root, name, rewrite, from, to, i, ln; if (this.enableNamespaceParseCache) { if (cache.hasOwnProperty(namespace)) { return cache[namespace]; } } parts = []; rewrites = this.namespaceRewrites; root = global; name = namespace; for (i = 0 , ln = rewrites.length; i < ln; i++) { rewrite = rewrites[i]; from = rewrite.from; to = rewrite.to; if (name === from || name.substring(0, from.length) === from) { name = name.substring(from.length); if (typeof to !== 'string') { root = to; } else { parts = parts.concat(to.split('.')); } break; } } parts.push(root); parts = parts.concat(name.split('.')); if (this.enableNamespaceParseCache) { cache[namespace] = parts; } return parts; }, setNamespace: function(name, value) { var root = global, parts = this.parseNamespace(name), ln = parts.length - 1, leaf = parts[ln], i, part; for (i = 0; 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 = 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 me = this, targetName = me.getName(value); me.classes[name] = me.setNamespace(name, value); if (targetName && targetName !== name) { me.addAlternate(targetName, name); } return this; }, get: function(name) { var classes = this.classes, root, parts, part, i, ln; if (classes[name]) { return classes[name]; } root = global; parts = this.parseNamespace(name); 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; }, addNameAliasMappings: function(aliases) { this.addAlias(aliases); }, addNameAlternateMappings: function(alternates) { this.addAlternate(alternates); }, getByAlias: function(alias) { return this.get(this.getNameByAlias(alias)); }, getName: function(object) { return object && object.$className || ''; }, getClass: function(object) { return object && object.self || null; }, create: function(className, data, createdFn) { if (className != null && typeof className !== 'string') { throw new Error("[Ext.define] Invalid class name '" + className + "' specified, must be a non-empty string"); } var ctor = makeCtor(className); if (typeof data === 'function') { data = data(ctor); } if (className) { if (Manager.classes[className]) { Ext.log.warn("[Ext.define] Duplicate class name '" + className + "' specified, must be a non-empty string"); } ctor.name = className; } data.$className = className; return new Class(ctor, data, function() { var postprocessorStack = data.postprocessors || Manager.defaultPostprocessors, registeredPostprocessors = Manager.postprocessors, postprocessors = [], postprocessor, i, ln, j, subLn, postprocessorProperties, postprocessorProperty; delete data.postprocessors; for (i = 0 , ln = postprocessorStack.length; i < ln; i++) { postprocessor = postprocessorStack[i]; if (typeof postprocessor === 'string') { postprocessor = registeredPostprocessors[postprocessor]; postprocessorProperties = postprocessor.properties; if (postprocessorProperties === true) { postprocessors.push(postprocessor.fn); } else if (postprocessorProperties) { for (j = 0 , subLn = postprocessorProperties.length; j < subLn; j++) { postprocessorProperty = postprocessorProperties[j]; if (data.hasOwnProperty(postprocessorProperty)) { postprocessors.push(postprocessor.fn); break; } } } } else { postprocessors.push(postprocessor); } } data.postprocessors = postprocessors; data.createdFn = createdFn; Manager.processCreate(className, this, data); }); }, processCreate: function(className, cls, clsData) { var me = this, postprocessor = clsData.postprocessors.shift(), createdFn = clsData.createdFn; if (!postprocessor) { Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#classCreated', arguments); if (className) { me.set(className, cls); } delete cls._classHooks; if (createdFn) { createdFn.call(cls, cls); } if (className) { me.triggerCreated(className); } return; } if (postprocessor.call(me, className, cls, clsData, me.processCreate) !== false) { me.processCreate(className, cls, clsData); } }, createOverride: function(className, data, createdFn) { var me = this, overriddenClassName = data.override, requires = data.requires, uses = data.uses, mixins = data.mixins, mixinsIsArray, compat = data.compatibility, depedenciesLoaded, classReady = function() { var cls, dependencies, i, key, temp; if (!depedenciesLoaded) { dependencies = requires ? requires.slice(0) : []; if (mixins) { if (!(mixinsIsArray = mixins instanceof Array)) { for (key in mixins) { if (Ext.isString(cls = mixins[key])) { dependencies.push(cls); } } } else { for (i = 0 , temp = mixins.length; i < temp; ++i) { if (Ext.isString(cls = mixins[i])) { dependencies.push(cls); } } } } depedenciesLoaded = true; if (dependencies.length) { Ext.require(dependencies, classReady); return; } } if (mixinsIsArray) { for (i = 0 , temp = mixins.length; i < temp; ++i) { if (Ext.isString(cls = mixins[i])) { mixins[i] = Ext.ClassManager.get(cls); } } } else if (mixins) { for (key in mixins) { if (Ext.isString(cls = mixins[key])) { mixins[key] = Ext.ClassManager.get(cls); } } } cls = me.get(overriddenClassName); delete data.override; delete data.compatibility; delete data.requires; delete data.uses; Ext.override(cls, data); Ext.Loader.history.push(className); if (uses) { Ext['Loader'].addUsedClasses(uses); } if (createdFn) { createdFn.call(cls, cls); } }; Manager.overrideMap[className] = true; if (!compat || Ext.checkVersion(compat)) { me.onCreated(classReady, me, overriddenClassName); } me.triggerCreated(className, 2); return me; }, instantiateByAlias: function() { var alias = arguments[0], args = arraySlice.call(arguments), className = this.getNameByAlias(alias); if (!className) { throw new Error("[Ext.createByAlias] Unrecognized alias: " + alias); } args[0] = className; return Ext.create.apply(Ext, args); }, instantiate: function() { Ext.log.warn('Ext.ClassManager.instantiate() is deprecated. Use Ext.create() instead.'); return Ext.create.apply(Ext, arguments); }, dynInstantiate: function(name, args) { args = arrayFrom(args, true); args.unshift(name); return Ext.create.apply(Ext, args); }, getInstantiator: function(length) { var instantiators = this.instantiators, instantiator, i, args; instantiator = instantiators[length]; if (!instantiator) { i = length; args = []; for (i = 0; i < length; i++) { args.push('a[' + i + ']'); } instantiator = instantiators[length] = new Function('c', 'a', 'return new c(' + args.join(',') + ')'); instantiator.name = "Ext.create" + length; } return instantiator; }, postprocessors: {}, defaultPostprocessors: [], registerPostprocessor: function(name, fn, properties, position, relativeTo) { if (!position) { position = 'last'; } if (!properties) { properties = [ name ]; } this.postprocessors[name] = { name: name, properties: properties || false, fn: fn }; this.setDefaultPostprocessorPosition(name, position, relativeTo); return this; }, setDefaultPostprocessors: function(postprocessors) { this.defaultPostprocessors = arrayFrom(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) { Ext.Array.splice(defaultPostprocessors, Math.max(0, index + offset), 0, name); } return this; } }); Manager.registerPostprocessor('alias', function(name, cls, data) { Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#aliasPostProcessor', arguments); var aliases = Ext.Array.from(data.alias), i, ln; for (i = 0 , ln = aliases.length; i < ln; i++) { alias = aliases[i]; this.addAlias(cls, alias); } }, [ 'xtype', 'alias' ]); Manager.registerPostprocessor('singleton', function(name, cls, data, fn) { Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#singletonPostProcessor', arguments); if (data.singleton) { fn.call(this, name, new cls(), data); } else { return true; } return false; }); Manager.registerPostprocessor('alternateClassName', function(name, cls, data) { Ext.classSystemMonitor && Ext.classSystemMonitor(name, 'Ext.ClassManager#alternateClassNamePostprocessor', arguments); 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') { throw new Error("[Ext.define] Invalid alternate of: '" + alternate + "' for class: '" + name + "'; must be a valid string"); } this.set(alternate, cls); } }); Manager.registerPostprocessor('debugHooks', function(name, Class, data) { Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#debugHooks', arguments); if (Ext.isDebugEnabled(Class.$className, data.debugHooks.$enabled)) { delete data.debugHooks.$enabled; Ext.override(Class, data.debugHooks); } var target = Class.isInstance ? Class.self : Class; delete target.prototype.debugHooks; }); Manager.registerPostprocessor('deprecated', function(name, Class, data) { Ext.classSystemMonitor && Ext.classSystemMonitor(Class, 'Ext.Class#deprecated', arguments); var target = Class.isInstance ? Class.self : Class; target.addDeprecations(data.deprecated); delete target.prototype.deprecated; }); Ext.apply(Ext, { create: function() { var name = arguments[0], nameType = typeof name, args = arraySlice.call(arguments, 1), cls; if (nameType === 'function') { cls = name; } else { if (nameType !== 'string' && args.length === 0) { args = [ name ]; if (!(name = name.xclass)) { name = args[0].xtype; if (name) { name = 'widget.' + name; } } } if (typeof name !== 'string' || name.length < 1) { throw new Error("[Ext.create] Invalid class name or alias '" + name + "' specified, must be a non-empty string"); } name = Manager.resolveName(name); cls = Manager.get(name); } if (!cls) { Ext.log.warn("[Ext.Loader] Synchronously loading '" + name + "'; consider adding " + "Ext.require('" + name + "') above Ext.onReady"); Ext.syncRequire(name); cls = Manager.get(name); } if (!cls) { throw new Error("[Ext.create] Unrecognized class name / alias: " + name); } if (typeof cls !== 'function') { throw new Error("[Ext.create] Singleton '" + name + "' cannot be instantiated."); } return Manager.getInstantiator(args.length)(cls, args); }, widget: function(name, config) { var xtype = name, alias, className, T; if (typeof xtype !== 'string') { config = name; xtype = config.xtype; className = config.xclass; } else { config = config || {}; } if (config.isComponent) { return config; } if (!className) { alias = 'widget.' + xtype; className = Manager.getNameByAlias(alias); } if (className) { T = Manager.get(className); } if (!T) { return Ext.create(className || alias, config); } return new T(config); }, createByAlias: alias(Manager, 'instantiateByAlias'), define: function(className, data, createdFn) { Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'ClassManager#define', arguments); if (data.override) { Manager.classState[className] = 20; return Manager.createOverride.apply(Manager, arguments); } Manager.classState[className] = 10; return Manager.create.apply(Manager, arguments); }, undefine: function(className) { Ext.classSystemMonitor && Ext.classSystemMonitor(className, 'Ext.ClassManager#undefine', arguments); var classes = Manager.classes, parts, partCount, namespace, i; delete Manager.namespaceParseCache[className]; delete classes[className]; delete Manager.existCache[className]; delete Manager.classState[className]; Manager.removeName(className); parts = Manager.parseNamespace(className); partCount = parts.length - 1; namespace = parts[0]; for (i = 1; i < partCount; i++) { namespace = namespace[parts[i]]; if (!namespace) { return; } } try { delete namespace[parts[partCount]]; } catch (e) { namespace[parts[partCount]] = undefined; } }, getClassName: alias(Manager, 'getName'), getDisplayName: function(object) { if (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 ('$className' in data) { cls.$className = data.$className; cls.displayName = cls.$className; } Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#classNamePreprocessor', arguments); }, true, 'first'); Class.registerPreprocessor('alias', function(cls, data) { Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor', arguments); var prototype = cls.prototype, xtypes = arrayFrom(data.xtype), aliases = arrayFrom(data.alias), widgetPrefix = 'widget.', widgetPrefixLength = widgetPrefix.length, xtypesChain = Array.prototype.slice.call(prototype.xtypesChain || []), xtypesMap = Ext.merge({}, prototype.xtypesMap || {}), i, ln, alias, xtype; for (i = 0 , ln = aliases.length; i < ln; i++) { alias = aliases[i]; if (typeof alias !== 'string' || alias.length < 1) { throw new Error("[Ext.define] Invalid alias of: '" + alias + "' for class: '" + name + "'; must be a valid string"); } if (alias.substring(0, widgetPrefixLength) === widgetPrefix) { xtype = alias.substring(widgetPrefixLength); Ext.Array.include(xtypes, xtype); } } cls.xtype = data.xtype = xtypes[0]; data.xtypes = xtypes; for (i = 0 , ln = xtypes.length; i < ln; i++) { xtype = xtypes[i]; if (!xtypesMap[xtype]) { xtypesMap[xtype] = true; xtypesChain.push(xtype); } } data.xtypesChain = xtypesChain; data.xtypesMap = xtypesMap; Ext.Function.interceptAfter(data, 'onClassCreated', function() { Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor#afterClassCreated', arguments); var mixins = prototype.mixins, key, mixin; for (key in mixins) { if (mixins.hasOwnProperty(key)) { mixin = mixins[key]; xtypes = mixin.xtypes; if (xtypes) { for (i = 0 , ln = xtypes.length; i < ln; i++) { xtype = xtypes[i]; if (!xtypesMap[xtype]) { xtypesMap[xtype] = true; xtypesChain.push(xtype); } } } } } }); for (i = 0 , ln = xtypes.length; i < ln; i++) { xtype = xtypes[i]; if (typeof xtype !== 'string' || xtype.length < 1) { throw new Error("[Ext.define] Invalid xtype of: '" + xtype + "' for class: '" + name + "'; must be a valid non-empty string"); } Ext.Array.include(aliases, widgetPrefix + xtype); } data.alias = aliases; }, [ 'xtype', 'alias' ]); if (Ext.manifest) { var manifest = Ext.manifest, classes = manifest.classes, paths = manifest.paths, aliases = {}, alternates = {}, className, obj, name, path, baseUrl; if (paths) { if (manifest.bootRelative) { baseUrl = Ext.Boot.baseUrl; for (path in paths) { if (paths.hasOwnProperty(path)) { paths[path] = baseUrl + paths[path]; } } } Manager.setPath(paths); } if (classes) { for (className in classes) { alternates[className] = []; aliases[className] = []; obj = classes[className]; if (obj.alias) { aliases[className] = obj.alias; } if (obj.alternates) { alternates[className] = obj.alternates; } } } Manager.addAlias(aliases); Manager.addAlternate(alternates); } return Manager; }(Ext.Class, Ext.Function.alias, Array.prototype.slice, Ext.Array.from, Ext.global)); (Ext.env || (Ext.env = {})).Browser = function(userAgent, publish) { var me = this, browserPrefixes = me.browserPrefixes, enginePrefixes = me.enginePrefixes, browserMatch = userAgent.match(new RegExp('((?:' + Ext.Object.getValues(browserPrefixes).join(')|(?:') + '))([\\w\\._]+)')), engineMatch = userAgent.match(new RegExp('((?:' + Ext.Object.getValues(enginePrefixes).join(')|(?:') + '))([\\w\\._]+)')), browserNames = me.browserNames, browserName = browserNames.other, engineNames = me.engineNames, engineName = engineNames.other, browserVersion = '', engineVersion = '', majorVer = '', isWebView = false, i, prefix, mode, name, maxIEVersion; me.userAgent = userAgent; if (browserMatch) { browserName = browserNames[Ext.Object.getKey(browserPrefixes, browserMatch[1])]; if (browserName === 'Safari' && /^Opera/.test(userAgent)) { browserName = 'Opera'; } browserVersion = new Ext.Version(browserMatch[2]); } if (engineMatch) { engineName = engineNames[Ext.Object.getKey(enginePrefixes, engineMatch[1])]; engineVersion = new Ext.Version(engineMatch[2]); } if (engineName === 'Trident' && browserName !== 'IE') { browserName = 'IE'; var version = userAgent.match(/.*rv:(\d+.\d+)/); if (version && version.length) { version = version[1]; browserVersion = new Ext.Version(version); } } if (userAgent.match(/FB/) && browserName === "Other") { browserName = browserNames.safari; engineName = engineNames.webkit; } if (userAgent.match(/Android.*Chrome/g)) { browserName = 'ChromeMobile'; } if (userAgent.match(/OPR/)) { browserName = 'Opera'; browserMatch = userAgent.match(/OPR\/(\d+.\d+)/); browserVersion = new Ext.Version(browserMatch[1]); } Ext.apply(this, { engineName: engineName, engineVersion: engineVersion, name: browserName, version: browserVersion }); this.setFlag(browserName, true, publish); if (browserVersion) { majorVer = browserVersion.getMajor() || ''; if (me.is.IE) { majorVer = parseInt(majorVer, 10); mode = document.documentMode; if (mode === 7 || (majorVer === 7 && mode !== 8 && mode !== 9 && mode !== 10)) { majorVer = 7; } else if (mode === 8 || (majorVer === 8 && mode !== 8 && mode !== 9 && mode !== 10)) { majorVer = 8; } else if (mode === 9 || (majorVer === 9 && mode !== 7 && mode !== 8 && mode !== 10)) { majorVer = 9; } else if (mode === 10 || (majorVer === 10 && mode !== 7 && mode !== 8 && mode !== 9)) { majorVer = 10; } else if (mode === 11 || (majorVer === 11 && mode !== 7 && mode !== 8 && mode !== 9 && mode !== 10)) { majorVer = 11; } maxIEVersion = Math.max(majorVer, 11); for (i = 7; i <= maxIEVersion; ++i) { prefix = 'isIE' + i; if (majorVer <= i) { Ext[prefix + 'm'] = true; } if (majorVer === i) { Ext[prefix] = true; } if (majorVer >= i) { Ext[prefix + 'p'] = true; } } } if (me.is.Opera && parseInt(majorVer, 10) <= 12) { Ext.isOpera12m = true; } Ext.chromeVersion = Ext.isChrome ? majorVer : 0; Ext.firefoxVersion = Ext.isFirefox ? majorVer : 0; Ext.ieVersion = Ext.isIE ? majorVer : 0; Ext.operaVersion = Ext.isOpera ? majorVer : 0; Ext.safariVersion = Ext.isSafari ? majorVer : 0; Ext.webKitVersion = Ext.isWebKit ? majorVer : 0; this.setFlag(browserName + majorVer, true, publish); this.setFlag(browserName + browserVersion.getShortVersion()); } for (i in browserNames) { if (browserNames.hasOwnProperty(i)) { name = browserNames[i]; this.setFlag(name, browserName === name); } } this.setFlag(name); if (engineVersion) { this.setFlag(engineName + (engineVersion.getMajor() || '')); this.setFlag(engineName + engineVersion.getShortVersion()); } for (i in engineNames) { if (engineNames.hasOwnProperty(i)) { name = engineNames[i]; this.setFlag(name, engineName === name, publish); } } this.setFlag('Standalone', !!navigator.standalone); this.setFlag('Ripple', !!document.getElementById("tinyhippos-injected") && !Ext.isEmpty(window.top.ripple)); this.setFlag('WebWorks', !!window.blackberry); if (window.PhoneGap !== undefined || window.Cordova !== undefined || window.cordova !== undefined) { isWebView = true; this.setFlag('PhoneGap'); this.setFlag('Cordova'); } else if (!!window.isNK) { isWebView = true; this.setFlag('Sencha'); } if (/(Glass)/i.test(userAgent)) { this.setFlag('GoogleGlass'); } if (/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)(?!.*FBAN)/i.test(userAgent)) { isWebView = true; } this.setFlag('WebView', isWebView); this.isStrict = Ext.isStrict = document.compatMode === "CSS1Compat"; this.isSecure = Ext.isSecure; this.identity = browserName + majorVer + (this.isStrict ? 'Strict' : 'Quirks'); }; Ext.env.Browser.prototype = { constructor: Ext.env.Browser, browserNames: { ie: 'IE', firefox: 'Firefox', safari: 'Safari', chrome: 'Chrome', opera: 'Opera', dolfin: 'Dolfin', webosbrowser: 'webOSBrowser', chromeMobile: 'ChromeMobile', chromeiOS: 'ChromeiOS', silk: 'Silk', other: 'Other' }, engineNames: { webkit: 'WebKit', gecko: 'Gecko', presto: 'Presto', trident: 'Trident', other: 'Other' }, enginePrefixes: { webkit: 'AppleWebKit/', gecko: 'Gecko/', presto: 'Presto/', trident: 'Trident/' }, browserPrefixes: { ie: 'MSIE ', firefox: 'Firefox/', chrome: 'Chrome/', safari: 'Version/', opera: 'OPR/', dolfin: 'Dolfin/', webosbrowser: 'wOSBrowser/', chromeMobile: 'CrMo/', chromeiOS: 'CriOS/', silk: 'Silk/' }, styleDashPrefixes: { WebKit: '-webkit-', Gecko: '-moz-', Trident: '-ms-', Presto: '-o-', Other: '' }, stylePrefixes: { WebKit: 'Webkit', Gecko: 'Moz', Trident: 'ms', Presto: 'O', Other: '' }, propertyPrefixes: { WebKit: 'webkit', Gecko: 'moz', Trident: 'ms', Presto: 'o', Other: '' }, is: function(name) { return !!this.is[name]; }, name: null, version: null, engineName: null, engineVersion: null, setFlag: function(name, value, publish) { if (value === undefined) { value = true; } this.is[name] = value; this.is[name.toLowerCase()] = value; if (publish) { Ext['is' + name] = value; } return this; }, getStyleDashPrefix: function() { return this.styleDashPrefixes[this.engineName]; }, getStylePrefix: function() { return this.stylePrefixes[this.engineName]; }, getVendorProperyName: function(name) { var prefix = this.propertyPrefixes[this.engineName]; if (prefix.length > 0) { return prefix + Ext.String.capitalize(name); } return name; }, getPreferredTranslationMethod: function(config) { if (typeof config === 'object' && 'translationMethod' in config && config.translationMethod !== 'auto') { return config.translationMethod; } else { return 'csstransform'; } } }; (function(userAgent) { Ext.browser = new Ext.env.Browser(userAgent, true); Ext.userAgent = userAgent.toLowerCase(); Ext.SSL_SECURE_URL = Ext.isSecure && Ext.isIE ? 'javascript:\'\'' : 'about:blank'; }( Ext.global.navigator.userAgent)); Ext.env.OS = function(userAgent, platform, browserScope) { var me = this, names = me.names, prefixes = me.prefixes, name, version = '', is = me.is, i, prefix, match, item, match1; browserScope = browserScope || Ext.browser; for (i in prefixes) { if (prefixes.hasOwnProperty(i)) { prefix = prefixes[i]; match = userAgent.match(new RegExp('(?:' + prefix + ')([^\\s;]+)')); if (match) { name = names[i]; match1 = match[1]; if (match1 && match1 === "HTC_") { version = new Ext.Version("2.3"); } else if (match1 && match1 === "Silk/") { version = new Ext.Version("2.3"); } else { version = new Ext.Version(match[match.length - 1]); } break; } } } if (!name) { name = names[(userAgent.toLowerCase().match(/mac|win|linux/) || [ 'other' ])[0]]; version = new Ext.Version(''); } this.name = name; this.version = version; if (platform) { this.setFlag(platform.replace(/ simulator$/i, '')); } this.setFlag(name); if (version) { this.setFlag(name + (version.getMajor() || '')); this.setFlag(name + version.getShortVersion()); } for (i in names) { if (names.hasOwnProperty(i)) { item = names[i]; if (!is.hasOwnProperty(name)) { this.setFlag(item, (name === item)); } } } if (this.name === "iOS" && window.screen.height === 568) { this.setFlag('iPhone5'); } if (browserScope.is.Safari || browserScope.is.Silk) { if (this.is.Android2 || this.is.Android3 || browserScope.version.shortVersion === 501) { browserScope.setFlag("AndroidStock"); browserScope.setFlag("AndroidStock2"); } if (this.is.Android4) { browserScope.setFlag("AndroidStock"); browserScope.setFlag("AndroidStock4"); } } }; Ext.env.OS.prototype = { constructor: Ext.env.OS, names: { ios: 'iOS', android: 'Android', windowsPhone: 'WindowsPhone', webos: 'webOS', blackberry: 'BlackBerry', rimTablet: 'RIMTablet', mac: 'MacOS', win: 'Windows', tizen: 'Tizen', linux: 'Linux', bada: 'Bada', chrome: 'ChromeOS', other: 'Other' }, prefixes: { tizen: '(Tizen )', ios: 'i(?:Pad|Phone|Pod)(?:.*)CPU(?: iPhone)? OS ', android: '(Android |HTC_|Silk/)', windowsPhone: 'Windows Phone ', blackberry: '(?:BlackBerry|BB)(?:.*)Version/', rimTablet: 'RIM Tablet OS ', webos: '(?:webOS|hpwOS)/', bada: 'Bada/', chrome: 'CrOS ' }, is: function(name) { return !!this[name]; }, name: null, version: null, setFlag: function(name, value) { if (value === undefined) { value = true; } if (this.flags) { this.flags[name] = value; } this.is[name] = value; this.is[name.toLowerCase()] = value; return this; } }; (function() { var navigation = Ext.global.navigator, userAgent = navigation.userAgent, OS = Ext.env.OS, is = (Ext.is || (Ext.is = {})), osEnv, osName, deviceType; OS.prototype.flags = is; Ext.os = osEnv = new OS(userAgent, navigation.platform); osName = osEnv.name; Ext['is' + osName] = true; Ext.isMac = is.Mac = is.MacOS; var search = window.location.search.match(/deviceType=(Tablet|Phone)/), nativeDeviceType = window.deviceType; if (search && search[1]) { deviceType = search[1]; } else if (nativeDeviceType === 'iPhone') { deviceType = 'Phone'; } else if (nativeDeviceType === 'iPad') { deviceType = 'Tablet'; } else { if (!osEnv.is.Android && !osEnv.is.iOS && !osEnv.is.WindowsPhone && /Windows|Linux|MacOS/.test(osName)) { deviceType = 'Desktop'; Ext.browser.is.WebView = !!Ext.browser.is.Ripple; } else if (osEnv.is.iPad || osEnv.is.RIMTablet || osEnv.is.Android3 || Ext.browser.is.Silk || (osEnv.is.Android4 && userAgent.search(/mobile/i) === -1)) { deviceType = 'Tablet'; } else { deviceType = 'Phone'; } } osEnv.setFlag(deviceType, true); osEnv.deviceType = deviceType; delete OS.prototype.flags; }()); Ext.feature = { has: function(name) { return !!this.has[name]; }, testElements: {}, getTestElement: function(tag, createNew) { if (tag === undefined) { tag = 'div'; } else if (typeof tag !== 'string') { return tag; } if (createNew) { return document.createElement(tag); } if (!this.testElements[tag]) { this.testElements[tag] = document.createElement(tag); } return this.testElements[tag]; }, isStyleSupported: function(name, tag) { var elementStyle = this.getTestElement(tag).style, cName = Ext.String.capitalize(name); if (typeof elementStyle[name] !== 'undefined' || typeof elementStyle[Ext.browser.getStylePrefix(name) + cName] !== 'undefined') { return true; } return false; }, isStyleSupportedWithoutPrefix: function(name, tag) { var elementStyle = this.getTestElement(tag).style; if (typeof elementStyle[name] !== 'undefined') { return true; } return false; }, isEventSupported: function(name, tag) { if (tag === undefined) { tag = window; } var element = this.getTestElement(tag), eventName = 'on' + name.toLowerCase(), isSupported = (eventName in element); if (!isSupported) { if (element.setAttribute && element.removeAttribute) { element.setAttribute(eventName, ''); isSupported = typeof element[eventName] === 'function'; if (typeof element[eventName] !== 'undefined') { element[eventName] = undefined; } element.removeAttribute(eventName); } } return isSupported; }, getStyle: function(element, styleName) { var view = element.ownerDocument.defaultView, style = (view ? view.getComputedStyle(element, null) : element.currentStyle); return (style || element.style)[styleName]; }, getSupportedPropertyName: function(object, name) { var vendorName = Ext.browser.getVendorProperyName(name); if (vendorName in object) { return vendorName; } else if (name in object) { return name; } return null; }, detect: function(isReady) { var me = this, doc = document, toRun = me.toRun || me.tests, n = toRun.length, div = doc.createElement('div'), notRun = [], supports = Ext.supports, has = me.has, name, test, vector, value; if (!Ext.theme) { Ext.theme = { name: 'Default' }; } Ext.theme.is = {}; Ext.theme.is[Ext.theme.name] = true; div.innerHTML = '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
'; if (isReady) { doc.body.appendChild(div); } vector = me.preDetected[Ext.browser.identity] || []; while (n--) { test = toRun[n]; value = vector[n]; name = test.name; if (value === undefined) { if (!isReady && test.ready) { notRun.push(test); continue; } value = test.fn.call(me, doc, div); } supports[name] = has[name] = value; } if (isReady) { doc.body.removeChild(div); } me.toRun = notRun; }, report: function() { var values = [], len = this.tests.length, i; for (i = 0; i < len; ++i) { values.push(this.has[this.tests[i].name] ? 1 : 0); } Ext.log(Ext.browser.identity + ': [' + values.join(',') + ']'); }, preDetected: {}, tests: [ { name: 'CSSPointerEvents', fn: function(doc) { return 'pointerEvents' in doc.documentElement.style; } }, { name: 'CSS3BoxShadow', fn: function(doc) { return 'boxShadow' in doc.documentElement.style || 'WebkitBoxShadow' in doc.documentElement.style || 'MozBoxShadow' in doc.documentElement.style; } }, { name: 'ClassList', fn: function(doc) { return !!doc.documentElement.classList; } }, { name: 'Canvas', fn: function() { var element = this.getTestElement('canvas'); return !!(element && element.getContext && element.getContext('2d')); } }, { name: 'Svg', fn: function(doc) { return !!(doc.createElementNS && !!doc.createElementNS("http:/" + "/www.w3.org/2000/svg", "svg").createSVGRect); } }, { name: 'Vml', fn: function() { var element = this.getTestElement(), ret = false; element.innerHTML = ""; ret = (element.childNodes.length === 1); element.innerHTML = ""; return ret; } }, { name: 'touchScroll', fn: function() { var supports = Ext.supports, touchScroll = 0; if (navigator.msMaxTouchPoints || (Ext.isWebKit && supports.TouchEvents && Ext.os.is.Desktop)) { touchScroll = 1; } else if (supports.Touch) { touchScroll = 2; } return touchScroll; } }, { name: 'Touch', fn: function() { var maxTouchPoints = navigator.msMaxTouchPoints || navigator.maxTouchPoints; return (Ext.supports.TouchEvents && maxTouchPoints !== 1) || maxTouchPoints > 1; } }, { name: 'TouchEvents', fn: function() { return this.isEventSupported('touchend'); } }, { name: 'PointerEvents', fn: function() { return navigator.pointerEnabled; } }, { name: 'MSPointerEvents', fn: function() { return navigator.msPointerEnabled; } }, { name: 'Orientation', fn: function() { return ('orientation' in window) && this.isEventSupported('orientationchange'); } }, { name: 'OrientationChange', fn: function() { return this.isEventSupported('orientationchange'); } }, { name: 'DeviceMotion', fn: function() { return this.isEventSupported('devicemotion'); } }, { names: [ 'Geolocation', 'GeoLocation' ], fn: function() { return 'geolocation' in window.navigator; } }, { name: 'SqlDatabase', fn: function() { return 'openDatabase' in window; } }, { name: 'WebSockets', fn: function() { return 'WebSocket' in window; } }, { name: 'Range', fn: function() { return !!document.createRange; } }, { name: 'CreateContextualFragment', fn: function() { var range = !!document.createRange ? document.createRange() : false; return range && !!range.createContextualFragment; } }, { name: 'History', fn: function() { return ('history' in window && 'pushState' in window.history); } }, { name: 'CssTransforms', fn: function() { return this.isStyleSupported('transform'); } }, { name: 'CssTransformNoPrefix', fn: function() { return this.isStyleSupportedWithoutPrefix('transform'); } }, { name: 'Css3dTransforms', fn: function() { return this.has('CssTransforms') && this.isStyleSupported('perspective') && !Ext.browser.is.AndroidStock2; } }, { name: 'CssAnimations', fn: function() { return this.isStyleSupported('animationName'); } }, { names: [ 'CssTransitions', 'Transitions' ], fn: function() { return this.isStyleSupported('transitionProperty'); } }, { names: [ 'Audio', 'AudioTag' ], fn: function() { return !!this.getTestElement('audio').canPlayType; } }, { name: 'Video', fn: function() { return !!this.getTestElement('video').canPlayType; } }, { name: 'LocalStorage', fn: function() { try { if ('localStorage' in window && window['localStorage'] !== null) { localStorage.setItem('sencha-localstorage-test', 'test success'); localStorage.removeItem('sencha-localstorage-test'); return true; } } catch (e) {} return false; } }, { name: 'XHR2', fn: function() { return window.ProgressEvent && window.FormData && window.XMLHttpRequest && ('withCredentials' in new XMLHttpRequest()); } }, { name: 'XHRUploadProgress', fn: function() { if (window.XMLHttpRequest && !Ext.browser.is.AndroidStock) { var xhr = new XMLHttpRequest(); return xhr && ('upload' in xhr) && ('onprogress' in xhr.upload); } return false; } }, { name: 'NumericInputPlaceHolder', fn: function() { return !(Ext.browser.is.AndroidStock4 && Ext.os.version.getMinor() < 2); } }, { name: 'ProperHBoxStretching', ready: true, fn: function() { var bodyElement = document.createElement('div'), innerElement = bodyElement.appendChild(document.createElement('div')), contentElement = innerElement.appendChild(document.createElement('div')), innerWidth; bodyElement.setAttribute('style', 'width: 100px; height: 100px; position: relative;'); innerElement.setAttribute('style', 'position: absolute; display: -ms-flexbox; display: -webkit-flex; display: -moz-flexbox; display: flex; -ms-flex-direction: row; -webkit-flex-direction: row; -moz-flex-direction: row; flex-direction: row; min-width: 100%;'); contentElement.setAttribute('style', 'width: 200px; height: 50px;'); document.body.appendChild(bodyElement); innerWidth = innerElement.offsetWidth; document.body.removeChild(bodyElement); return (innerWidth > 100); } }, { name: 'matchesSelector', fn: function() { var el = document.documentElement, w3 = 'matches', wk = 'webkitMatchesSelector', ms = 'msMatchesSelector', mz = 'mozMatchesSelector'; return el[w3] ? w3 : el[wk] ? wk : el[ms] ? ms : el[mz] ? mz : null; } }, { name: 'RightMargin', ready: true, fn: function(doc, div) { var view = doc.defaultView; return !(view && view.getComputedStyle(div.firstChild.firstChild, null).marginRight !== '0px'); } }, { name: 'DisplayChangeInputSelectionBug', fn: function() { var webKitVersion = Ext.webKitVersion; return 0 < webKitVersion && webKitVersion < 533; } }, { name: 'DisplayChangeTextAreaSelectionBug', fn: function() { var webKitVersion = Ext.webKitVersion; return 0 < webKitVersion && webKitVersion < 534.24; } }, { name: 'TransparentColor', ready: true, fn: function(doc, div, view) { view = doc.defaultView; return !(view && view.getComputedStyle(div.lastChild, null).backgroundColor !== 'transparent'); } }, { name: 'ComputedStyle', ready: true, fn: function(doc, div, view) { view = doc.defaultView; return view && view.getComputedStyle; } }, { name: 'Float', fn: function(doc) { return 'cssFloat' in doc.documentElement.style; } }, { name: 'CSS3BorderRadius', ready: true, fn: function(doc) { var domPrefixes = [ 'borderRadius', 'BorderRadius', 'MozBorderRadius', 'WebkitBorderRadius', 'OBorderRadius', 'KhtmlBorderRadius' ], pass = false, i; for (i = 0; i < domPrefixes.length; i++) { if (doc.documentElement.style[domPrefixes[i]] !== undefined) { pass = true; } } return pass && !Ext.isIE9; } }, { name: '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, ms = '-ms-' + w3c, opera = '-o-' + w3c, options = [ property + webkit, property + w3c, property + moz, property + ms, property + opera ]; div.style.cssText = options.join(';'); return (("" + div.style.backgroundImage).indexOf('gradient') !== -1) && !Ext.isIE9; } }, { name: 'MouseEnterLeave', fn: function(doc) { return ('onmouseenter' in doc.documentElement && 'onmouseleave' in doc.documentElement); } }, { name: 'MouseWheel', fn: function(doc) { return ('onmousewheel' in doc.documentElement); } }, { name: 'Opacity', fn: function(doc, div) { if (Ext.isIE8) { return false; } div.firstChild.style.cssText = 'opacity:0.73'; return div.firstChild.style.opacity == '0.73'; } }, { name: 'Placeholder', fn: function(doc) { return 'placeholder' in doc.createElement('input'); } }, { name: 'Direct2DBug', fn: function(doc) { return Ext.isString(doc.documentElement.style.msTransformOrigin) && Ext.isIE9m; } }, { name: 'BoundingClientRect', fn: function(doc) { return 'getBoundingClientRect' in doc.documentElement; } }, { name: 'RotatedBoundingClientRect', ready: true, fn: function(doc) { var body = doc.body, supports = false, el = this.getTestElement(), style = el.style; if (el.getBoundingClientRect) { style.WebkitTransform = style.MozTransform = style.msTransform = style.OTransform = style.transform = 'rotate(90deg)'; style.width = '100px'; style.height = '30px'; body.appendChild(el); supports = el.getBoundingClientRect().height !== 100; body.removeChild(el); } return supports; } }, { name: 'ChildContentClearedWhenSettingInnerHTML', ready: true, fn: function() { var el = this.getTestElement(), child; el.innerHTML = '
a
'; child = el.firstChild; el.innerHTML = '
b
'; return child.innerHTML !== 'a'; } }, { name: 'IncludePaddingInWidthCalculation', ready: true, fn: function(doc, div) { return div.childNodes[1].firstChild.offsetWidth === 210; } }, { name: 'IncludePaddingInHeightCalculation', ready: true, fn: function(doc, div) { return div.childNodes[1].firstChild.offsetHeight === 210; } }, { name: 'TextAreaMaxLength', fn: function(doc) { return ('maxlength' in doc.createElement('textarea')); } }, { name: 'GetPositionPercentage', ready: true, fn: function(doc, div) { return Ext.feature.getStyle(div.childNodes[2], 'left') === '10%'; } }, { name: 'PercentageHeightOverflowBug', ready: true, fn: function(doc) { var hasBug = false, style, el; if (Ext.getScrollbarSize().height) { el = this.getTestElement(); style = el.style; style.height = '50px'; style.width = '50px'; style.overflow = 'auto'; style.position = 'absolute'; el.innerHTML = [ '
', '
', '
' ].join(''); doc.body.appendChild(el); if (el.firstChild.offsetHeight === 50) { hasBug = true; } doc.body.removeChild(el); } return hasBug; } }, { name: 'xOriginBug', ready: true, fn: function(doc, div) { div.innerHTML = '
' + '
' + '
' + '
'; var outerBox = document.getElementById('b1').getBoundingClientRect(), b2 = document.getElementById('b2').getBoundingClientRect(), b3 = document.getElementById('b3').getBoundingClientRect(); return (b2.left !== outerBox.left && b3.right !== outerBox.right); } }, { name: 'ScrollWidthInlinePaddingBug', ready: true, fn: function(doc) { var hasBug = false, style, el; el = doc.createElement('div'); style = el.style; style.height = '50px'; style.width = '50px'; style.padding = '10px'; style.overflow = 'hidden'; style.position = 'absolute'; el.innerHTML = ''; doc.body.appendChild(el); if (el.scrollWidth === 70) { hasBug = true; } doc.body.removeChild(el); return hasBug; } }, { name: 'rtlVertScrollbarOnRight', ready: true, fn: function(doc, div) { div.innerHTML = '
' + '
' + '
'; var outerBox = div.firstChild, innerBox = outerBox.firstChild; return (innerBox.offsetLeft + innerBox.offsetWidth !== outerBox.offsetLeft + outerBox.offsetWidth); } }, { name: 'rtlVertScrollbarOverflowBug', ready: true, fn: function(doc, div) { div.innerHTML = '
' + '
' + '
'; var outerBox = div.firstChild; return outerBox.clientHeight === outerBox.offsetHeight; } }, { identity: 'defineProperty', fn: function() { if (Ext.isIE8m) { Ext.Object.defineProperty = Ext.emptyFn; return false; } return true; } }, { identify: 'nativeXhr', fn: function() { if (typeof XMLHttpRequest !== 'undefined') { return true; } XMLHttpRequest = function() { try { return new ActiveXObject('MSXML2.XMLHTTP.3.0'); } catch (ex) { return null; } }; return false; } }, { name: 'SpecialKeyDownRepeat', fn: function() { return Ext.isWebKit ? parseInt(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1], 10) >= 525 : !((Ext.isGecko && !Ext.isWindows) || (Ext.isOpera && Ext.operaVersion < 12)); } }, { name: 'EmulatedMouseOver', fn: function() { return Ext.os.is.iOS; } }, { name: 'Hashchange', fn: function() { var docMode = document.documentMode; return 'onhashchange' in window && (docMode === undefined || docMode > 7); } }, { name: 'FixedTableWidthBug', ready: true, fn: function() { if (Ext.isIE8) { return false; } var outer = document.createElement('div'), inner = document.createElement('div'), width; outer.setAttribute('style', 'display:table;table-layout:fixed;'); inner.setAttribute('style', 'display:table-cell;min-width:50px;'); outer.appendChild(inner); document.body.appendChild(outer); outer.offsetWidth; outer.style.width = '25px'; width = outer.offsetWidth; document.body.removeChild(outer); return width === 50; } }, { name: 'FocusinFocusoutEvents', fn: function() { return !Ext.isGecko; } }, 0 ] }; Ext.feature.tests.pop(); Ext.supports = {}; Ext.feature.detect(); Ext.env.Ready = { blocks: (location.search || '').indexOf('ext-pauseReadyFire') > 0 ? 1 : 0, bound: 0, delay: 1, events: [], firing: false, generation: 0, listeners: [], nextId: 0, sortGeneration: 0, state: 0, timer: null, bind: function() { var me = Ext.env.Ready, doc = document; if (!me.bound) { if (doc.readyState === 'complete') { me.onReadyEvent({ type: doc.readyState || 'body' }); } else { me.bound = 1; if (Ext.browser.is.PhoneGap && !Ext.os.is.Desktop) { me.bound = 2; doc.addEventListener('deviceready', me.onReadyEvent, false); } doc.addEventListener('DOMContentLoaded', me.onReadyEvent, false); window.addEventListener('load', me.onReadyEvent, false); } } }, block: function() { ++this.blocks; Ext.isReady = false; }, fireReady: function() { var me = Ext.env.Ready; if (!me.state) { Ext._readyTime = Ext.now(); Ext.isDomReady = true; me.state = 1; Ext.feature.detect(true); if (!me.delay) { me.handleReady(); } else if (navigator.standalone) { me.timer = Ext.defer(function() { me.timer = null; me.handleReadySoon(); }, 1); } else { me.handleReadySoon(); } } }, handleReady: function() { var me = this; if (me.state === 1) { me.state = 2; Ext._beforeReadyTime = Ext.now(); me.invokeAll(); Ext._afterReadytime = Ext.now(); } }, handleReadySoon: function(delay) { var me = this; if (!me.timer) { me.timer = Ext.defer(function() { me.timer = null; me.handleReady(); }, delay || me.delay); } }, invoke: function(listener) { var delay = listener.delay; if (delay) { Ext.defer(listener.fn, delay, listener.scope); } else { if (Ext.elevateFunction) { Ext.elevateFunction(listener.fn, listener.scope); } else { listener.fn.call(listener.scope); } } }, invokeAll: function() { if (Ext.elevateFunction) { Ext.elevateFunction(this.doInvokeAll, this); } else { this.doInvokeAll(); } }, doInvokeAll: function() { var me = this, listeners = me.listeners, listener; if (!me.blocks) { Ext.isReady = true; } me.firing = true; while (listeners.length) { if (me.sortGeneration !== me.generation) { me.sortGeneration = me.generation; listeners.sort(me.sortFn); } listener = listeners.pop(); if (me.blocks && !listener.dom) { listeners.push(listener); break; } me.invoke(listener); } me.firing = false; }, makeListener: function(fn, scope, options) { var ret = { fn: fn, id: ++this.nextId, scope: scope, dom: false, priority: 0 }; if (options) { Ext.apply(ret, options); } ret.phase = ret.dom ? 0 : 1; return ret; }, on: function(fn, scope, options) { var me = Ext.env.Ready, listener = me.makeListener(fn, scope, options); if (me.state === 2 && !me.firing && (listener.dom || !me.blocks)) { me.invoke(listener); } else { me.listeners.push(listener); ++me.generation; if (!me.bound) { me.bind(); } } }, onReadyEvent: function(ev) { var me = Ext.env.Ready; if (Ext.elevateFunction) { Ext.elevateFunction(me.doReadyEvent, me, arguments); } else { me.doReadyEvent(ev); } }, doReadyEvent: function(ev) { var me = this; if (ev && ev.type) { me.events.push(ev); } if (me.bound > 0) { me.unbind(); me.bound = -1; } if (!me.state) { me.fireReady(); } }, sortFn: function(a, b) { return -((a.phase - b.phase) || (b.priority - a.priority) || (a.id - b.id)); }, unblock: function() { var me = this; if (me.blocks) { if (!--me.blocks) { if (me.state === 2 && !me.firing) { me.invokeAll(); } } } }, unbind: function() { var me = this, doc = document; if (me.bound > 1) { doc.removeEventListener('deviceready', me.onReadyEvent, false); } doc.removeEventListener('DOMContentLoaded', me.onReadyEvent, false); window.removeEventListener('load', me.onReadyEvent, false); } }; (function() { var Ready = Ext.env.Ready; if (Ext.isIE9m) { Ext.apply(Ready, { scrollTimer: null, readyStatesRe: /complete/i, pollScroll: function() { var scrollable = true; try { document.documentElement.doScroll('left'); } catch (e) { scrollable = false; } if (scrollable && document.body) { Ready.onReadyEvent({ type: 'doScroll' }); } else { Ready.scrollTimer = Ext.defer(Ready.pollScroll, 20); } return scrollable; }, bind: function() { if (Ready.bound) { return; } var doc = document, topContext; try { topContext = window.frameElement === undefined; } catch (e) {} if (!topContext || !doc.documentElement.doScroll) { Ready.pollScroll = Ext.emptyFn; } else if (Ready.pollScroll()) { return; } if (doc.readyState === 'complete') { Ready.onReadyEvent({ type: 'already ' + (doc.readyState || 'body') }); } else { doc.attachEvent('onreadystatechange', Ready.onReadyStateChange); window.attachEvent('onload', Ready.onReadyEvent); Ready.bound = 1; } }, unbind: function() { document.detachEvent('onreadystatechange', Ready.onReadyStateChange); window.detachEvent('onload', Ready.onReadyEvent); if (Ext.isNumber(Ready.scrollTimer)) { clearTimeout(Ready.scrollTimer); Ready.scrollTimer = null; } }, onReadyStateChange: function() { var state = document.readyState; if (Ready.readyStatesRe.test(state)) { Ready.onReadyEvent({ type: state }); } } }); } Ext.onDocumentReady = function(fn, scope, options) { var opt = { dom: true }; if (options) { Ext.apply(opt, options); } Ready.on(fn, scope, opt); }; Ext.onReady = function(fn, scope, options) { Ready.on(fn, scope, options); }; Ext.onInternalReady = function(fn, scope, options) { Ready.on(fn, scope, Ext.apply({ priority: 1000 }, options)); }; Ready.bind(); }()); Ext.Loader = (new function() { var Loader = this, Manager = Ext.ClassManager, Boot = Ext.Boot, Class = Ext.Class, Ready = Ext.env.Ready, alias = Ext.Function.alias, dependencyProperties = [ 'extend', 'mixins', 'requires' ], isInHistory = {}, history = [], readyListeners = [], usedClasses = [], _requiresMap = {}, _missingQueue = {}, _config = { enabled: true, scriptChainDelay: false, disableCaching: true, disableCachingParam: '_dc', paths: Manager.paths, preserveScripts: true, scriptCharset: undefined }, delegatedConfigs = { disableCaching: true, disableCachingParam: true, preserveScripts: true, scriptChainDelay: 'loadDelay' }; Ext.apply(Loader, { isInHistory: isInHistory, isLoading: false, history: history, config: _config, readyListeners: readyListeners, optionalRequires: usedClasses, requiresMap: _requiresMap, hasFileLoadError: false, scriptsLoading: 0, classesLoading: [], syncModeEnabled: false, missingQueue: _missingQueue, init: function() { var scripts = document.getElementsByTagName('script'), src = scripts[scripts.length - 1].src, path = src.substring(0, src.lastIndexOf('/') + 1), meta = Ext._classPathMetadata, microloader = Ext.Microloader, manifest = Ext.manifest, loadOrder, baseUrl, loadlen, l, loadItem; if (src.indexOf("packages/sencha-core/src/") !== -1) { path = path + "../../"; } else if (src.indexOf("/core/src/class/") !== -1) { path = path + "../../../"; } if (!Manager.getPath("Ext")) { Manager.setPath('Ext', path + 'src'); } if (meta) { Ext._classPathMetadata = null; Loader.addClassPathMappings(meta); } if (manifest) { loadOrder = manifest.loadOrder; baseUrl = Ext.Boot.baseUrl; if (loadOrder && manifest.bootRelative) { for (loadlen = loadOrder.length , l = 0; l < loadlen; l++) { loadItem = loadOrder[l]; loadItem.path = baseUrl + loadItem.path; } } } if (microloader) { Ready.block(); microloader.onMicroloaderReady(function() { Ready.unblock(); }); } }, setConfig: Ext.Function.flexSetter(function(name, value) { if (name === 'paths') { Loader.setPath(value); } else { _config[name] = value; var delegated = delegatedConfigs[name]; if (delegated) { Boot.setConfig((delegated === true) ? name : delegated, value); } } return Loader; }), getConfig: function(name) { return name ? _config[name] : _config; }, setPath: function() { Manager.setPath.apply(Manager, arguments); return Loader; }, addClassPathMappings: function(paths) { Manager.setPath(paths); return Loader; }, addBaseUrlClassPathMappings: function(pathConfig) { for (var name in pathConfig) { pathConfig[name] = Boot.baseUrl + pathConfig[name]; } Ext.Loader.addClassPathMappings(pathConfig); }, getPath: function(className) { return Manager.getPath(className); }, require: function(expressions, fn, scope, excludes) { if (excludes) { return Loader.exclude(excludes).require(expressions, fn, scope); } var classNames = Manager.getNamesByExpression(expressions); return Loader.load(classNames, fn, scope); }, syncRequire: function() { var wasEnabled = Loader.syncModeEnabled; Loader.syncModeEnabled = true; var ret = Loader.require.apply(Loader, arguments); Loader.syncModeEnabled = wasEnabled; return ret; }, exclude: function(excludes) { var selector = Manager.select({ require: function(classNames, fn, scope) { return Loader.load(classNames, fn, scope); }, syncRequire: function(classNames, fn, scope) { var wasEnabled = Loader.syncModeEnabled; Loader.syncModeEnabled = true; var ret = Loader.load(classNames, fn, scope); Loader.syncModeEnabled = wasEnabled; return ret; } }); selector.exclude(excludes); return selector; }, load: function(classNames, callback, scope) { if (callback) { if (callback.length) { callback = Loader.makeLoadCallback(classNames, callback); } callback = callback.bind(scope || Ext.global); } var missingClassNames = [], numClasses = classNames.length, className, i, numMissing, urls = [], state = Manager.classState; for (i = 0; i < numClasses; ++i) { className = Manager.resolveName(classNames[i]); if (!Manager.isCreated(className)) { missingClassNames.push(className); _missingQueue[className] = Loader.getPath(className); if (!state[className]) { urls.push(_missingQueue[className]); } } } numMissing = missingClassNames.length; if (numMissing) { Loader.missingCount += numMissing; Ext.Array.push(Loader.classesLoading, missingClassNames); Manager.onCreated(function() { Ext.Array.remove(Loader.classesLoading, missingClassNames); Ext.each(missingClassNames, function(name) { Ext.Array.remove(Loader.classesLoading, name); }); if (callback) { Ext.callback(callback, scope, arguments); } Loader.checkReady(); }, Loader, missingClassNames); if (!_config.enabled) { Ext.Error.raise("Ext.Loader is not enabled, so dependencies cannot be resolved dynamically. " + "Missing required class" + ((missingClassNames.length > 1) ? "es" : "") + ": " + missingClassNames.join(', ')); } if (urls.length) { Loader.loadScripts({ url: urls, _classNames: missingClassNames }); } else { Loader.checkReady(); } } else { if (callback) { callback.call(scope); } Loader.checkReady(); } if (Loader.syncModeEnabled) { if (numClasses === 1) { return Manager.get(classNames[0]); } } return Loader; }, makeLoadCallback: function(classNames, callback) { return function() { var classes = [], i = classNames.length; while (i-- > 0) { classes[i] = Manager.get(classNames[i]); } return callback.apply(this, classes); }; }, onLoadFailure: function() { var options = this, onError = options.onError; Loader.hasFileLoadError = true; --Loader.scriptsLoading; if (onError) { onError.call(options.userScope, options); } else { Ext.log.error("[Ext.Loader] Some requested files failed to load."); } Loader.checkReady(); }, onLoadSuccess: function() { var options = this, onLoad = options.onLoad; --Loader.scriptsLoading; if (onLoad) { onLoad.call(options.userScope, options); } Loader.checkReady(); }, reportMissingClasses: function() { if (!Loader.syncModeEnabled && !Loader.scriptsLoading && Loader.isLoading && !Loader.hasFileLoadError) { var missingClasses = [], missingPaths = []; for (var missingClassName in _missingQueue) { missingClasses.push(missingClassName); missingPaths.push(_missingQueue[missingClassName]); } if (missingClasses.length) { throw new Error("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("', '")); } } }, onReady: function(fn, scope, withDomReady, options) { if (withDomReady) { Ready.on(fn, scope, options); } else { var listener = Ready.makeListener(fn, scope, options); if (Loader.isLoading) { readyListeners.push(listener); } else { Ready.invoke(listener); } } }, addUsedClasses: function(classes) { var cls, i, ln; if (classes) { classes = (typeof classes === 'string') ? [ classes ] : classes; for (i = 0 , ln = classes.length; i < ln; i++) { cls = classes[i]; if (typeof cls === 'string' && !Ext.Array.contains(usedClasses, cls)) { usedClasses.push(cls); } } } return Loader; }, triggerReady: function() { var listener, refClasses = usedClasses; if (Loader.isLoading && refClasses.length) { usedClasses = []; Loader.require(refClasses); } else { Loader.isLoading = false; readyListeners.sort(Ready.sortFn); while (readyListeners.length && !Loader.isLoading) { listener = readyListeners.pop(); Ready.invoke(listener); } Ready.unblock(); } }, historyPush: function(className) { if (className && !isInHistory[className] && !Manager.overrideMap[className]) { isInHistory[className] = true; history.push(className); } return Loader; }, loadScripts: function(params) { var manifest = Ext.manifest, loadOrder = manifest && manifest.loadOrder, loadOrderMap = manifest && manifest.loadOrderMap, options; ++Loader.scriptsLoading; if (loadOrder && !loadOrderMap) { manifest.loadOrderMap = loadOrderMap = Boot.createLoadOrderMap(loadOrder); } Loader.checkReady(); options = Ext.apply({ loadOrder: loadOrder, loadOrderMap: loadOrderMap, charset: _config.scriptCharset, success: Loader.onLoadSuccess, failure: Loader.onLoadFailure, sync: Loader.syncModeEnabled, _classNames: [] }, params); options.userScope = options.scope; options.scope = options; Boot.load(options); }, loadScriptsSync: function(urls) { var syncwas = Loader.syncModeEnabled; Loader.syncModeEnabled = true; Loader.loadScripts({ url: urls }); Loader.syncModeEnabled = syncwas; }, loadScriptsSyncBasePrefix: function(urls) { var syncwas = Loader.syncModeEnabled; Loader.syncModeEnabled = true; Loader.loadScripts({ url: urls, prependBaseUrl: true }); Loader.syncModeEnabled = syncwas; }, loadScript: function(options) { var isString = typeof options === 'string', isArray = options instanceof Array, isObject = !isArray && !isString, url = isObject ? options.url : options, onError = isObject && options.onError, onLoad = isObject && options.onLoad, scope = isObject && options.scope, request = { url: url, scope: scope, onLoad: onLoad, onError: onError, _classNames: [] }; Loader.loadScripts(request); }, flushMissingQueue: function() { var name, val, missingwas = 0, missing = 0; for (name in _missingQueue) { missingwas++; val = _missingQueue[name]; if (Manager.isCreated(name)) { delete _missingQueue[name]; } else if (Manager.existCache[name] === 2) { delete _missingQueue[name]; } else { ++missing; } } this.missingCount = missing; }, checkReady: function() { var wasLoading = Loader.isLoading, isLoading; Loader.flushMissingQueue(); isLoading = Loader.missingCount + Loader.scriptsLoading; if (isLoading && !wasLoading) { Ready.block(); Loader.isLoading = !!isLoading; } else if (!isLoading && wasLoading) { Loader.triggerReady(); } } }); Ext.require = alias(Loader, 'require'); Ext.syncRequire = alias(Loader, 'syncRequire'); Ext.exclude = alias(Loader, 'exclude'); Class.registerPreprocessor('loader', function(cls, data, hooks, continueFn) { Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.Loader#loaderPreprocessor', arguments); var me = this, dependencies = [], dependency, className = Manager.getName(cls), i, j, ln, subLn, value, propertyName, propertyValue, requiredMap; 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 if (typeof propertyValue !== 'function') { for (j in propertyValue) { if (propertyValue.hasOwnProperty(j)) { value = propertyValue[j]; if (typeof value === 'string') { dependencies.push(value); } } } } } } if (dependencies.length === 0) { return; } if (className) { _requiresMap[className] = dependencies; } var deadlockPath = [], detectDeadlock; if (className) { requiredMap = Loader.requiredByMap || (Loader.requiredByMap = {}); for (i = 0 , ln = dependencies.length; i < ln; i++) { dependency = dependencies[i]; (requiredMap[dependency] || (requiredMap[dependency] = [])).push(className); } detectDeadlock = function(cls) { deadlockPath.push(cls); if (_requiresMap[cls]) { if (Ext.Array.contains(_requiresMap[cls], className)) { Ext.Error.raise("Circular requirement detected! '" + 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); } (className ? Loader.exclude(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 if (typeof propertyValue !== 'function') { 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, hooks); }); return false; }, true, 'after', 'className'); Manager.registerPostprocessor('uses', function(name, cls, data) { Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.Loader#usesPostprocessor', arguments); var manifest = Ext.manifest, loadOrder = manifest && manifest.loadOrder, classes = manifest && manifest.classes, uses, clazz, item, len, i, indexMap; if (loadOrder) { clazz = classes[name]; if (clazz && !isNaN(i = clazz.idx)) { item = loadOrder[i]; uses = item.uses; indexMap = {}; for (len = uses.length , i = 0; i < len; i++) { indexMap[uses[i]] = true; } uses = Ext.Boot.getPathsFromIndexes(indexMap, loadOrder, true); if (uses.length > 0) { Loader.loadScripts({ url: uses, sequential: true }); } } } if (data.uses) { uses = data.uses; Loader.addUsedClasses(uses); } }); Manager.onCreated(Loader.historyPush); Loader.init(); }()); Ext._endTime = new Date().getTime(); if (Ext._beforereadyhandler) { Ext._beforereadyhandler(); } Ext.define('Ext.Mixin', function(Mixin) { return { statics: { addHook: function(hookFn, targetClass, methodName, mixinClassPrototype) { var isFunc = Ext.isFunction(hookFn), hook = function() { var a = arguments, fn = isFunc ? hookFn : mixinClassPrototype[hookFn], result = this.callParent(a); fn.apply(this, a); return result; }, existingFn = targetClass.hasOwnProperty(methodName) && targetClass[methodName]; if (isFunc) { hookFn.$previous = Ext.emptyFn; } hook.$name = methodName; hook.$owner = targetClass.self; if (existingFn) { hook.$previous = existingFn.$previous; existingFn.$previous = hook; } else { targetClass[methodName] = hook; } } }, onClassExtended: function(cls, data) { var mixinConfig = data.mixinConfig, hooks = data.xhooks, superclass = cls.superclass, onClassMixedIn = data.onClassMixedIn, parentMixinConfig, befores, afters, extended; if (hooks) { delete data.xhooks; (mixinConfig || (data.mixinConfig = mixinConfig = {})).on = hooks; } if (mixinConfig) { parentMixinConfig = superclass.mixinConfig; if (parentMixinConfig) { data.mixinConfig = mixinConfig = Ext.merge({}, parentMixinConfig, mixinConfig); } data.mixinId = mixinConfig.id; if (mixinConfig.beforeHooks) { Ext.Error.raise('Use of "beforeHooks" is deprecated - use "before" instead'); } if (mixinConfig.hooks) { Ext.Error.raise('Use of "hooks" is deprecated - use "after" instead'); } if (mixinConfig.afterHooks) { Ext.Error.raise('Use of "afterHooks" is deprecated - use "after" instead'); } befores = mixinConfig.before; afters = mixinConfig.after; hooks = mixinConfig.on; extended = mixinConfig.extended; } if (befores || afters || hooks || extended) { data.onClassMixedIn = function(targetClass) { var mixin = this.prototype, targetProto = targetClass.prototype, key; if (befores) { Ext.Object.each(befores, function(key, value) { targetClass.addMember(key, function() { if (mixin[value].apply(this, arguments) !== false) { return this.callParent(arguments); } }); }); } if (afters) { Ext.Object.each(afters, function(key, value) { targetClass.addMember(key, function() { var ret = this.callParent(arguments); mixin[value].apply(this, arguments); return ret; }); }); } if (hooks) { for (key in hooks) { Mixin.addHook(hooks[key], targetProto, key, mixin); } } if (extended) { targetClass.onExtended(function() { var args = Ext.Array.slice(arguments, 0); args.unshift(targetClass); return extended.apply(this, args); }, this); } if (onClassMixedIn) { onClassMixedIn.apply(this, arguments); } }; } } }; }); Ext.util = Ext.util || {}; Ext.util.DelayedTask = function(fn, scope, args, cancelOnDelay, fireIdleEvent) { var me = this, delay, call = function() { var globalEvents = Ext.GlobalEvents; clearInterval(me.id); me.id = null; fn.apply(scope, args || []); if (fireIdleEvent !== false && globalEvents.hasListeners.idle) { globalEvents.fireEvent('idle'); } }; cancelOnDelay = typeof cancelOnDelay === 'boolean' ? cancelOnDelay : true; me.id = null; me.delay = function(newDelay, newFn, newScope, newArgs) { if (cancelOnDelay) { me.cancel(); } if (typeof newDelay === 'number') { delay = newDelay; } fn = newFn || fn; scope = newScope || scope; args = newArgs || args; if (!me.id) { me.id = Ext.interval(call, delay); } }; me.cancel = function() { if (me.id) { clearInterval(me.id); me.id = null; } }; }; Ext.define('Ext.util.Event', function() { var arraySlice = Array.prototype.slice, arrayInsert = Ext.Array.insert, toArray = Ext.Array.toArray, fireArgs = {}; return { requires: 'Ext.util.DelayedTask', isEvent: true, suspended: 0, noOptions: {}, constructor: function(observable, name) { this.name = name; this.observable = observable; this.listeners = []; }, addListener: function(fn, scope, options, caller, manager) { var me = this, added = false, observable = me.observable, eventName = me.name, listeners, listener, priority, isNegativePriority, highestNegativePriorityIndex, hasNegativePriorityIndex, length, index, i, listenerPriority; if (scope && !Ext._namedScopes[scope] && (typeof fn === 'string') && (typeof scope[fn] !== 'function')) { Ext.Error.raise("No method named '" + fn + "' found on scope object"); } if (me.findListener(fn, scope) === -1) { listener = me.createListener(fn, scope, options, caller, manager); if (me.firing) { me.listeners = me.listeners.slice(0); } listeners = me.listeners; index = length = listeners.length; priority = options && options.priority; highestNegativePriorityIndex = me._highestNegativePriorityIndex; hasNegativePriorityIndex = highestNegativePriorityIndex !== undefined; if (priority) { isNegativePriority = (priority < 0); if (!isNegativePriority || hasNegativePriorityIndex) { for (i = (isNegativePriority ? highestNegativePriorityIndex : 0); i < length; i++) { listenerPriority = listeners[i].o ? listeners[i].o.priority || 0 : 0; if (listenerPriority < priority) { index = i; break; } } } else { me._highestNegativePriorityIndex = index; } } else if (hasNegativePriorityIndex) { index = highestNegativePriorityIndex; } if (!isNegativePriority && index <= highestNegativePriorityIndex) { me._highestNegativePriorityIndex++; } if (index === length) { listeners[length] = listener; } else { arrayInsert(listeners, index, [ listener ]); } if (observable.isElement) { observable._getPublisher(eventName).subscribe(observable, eventName, options.delegated !== false, options.capture); } added = true; } return added; }, createListener: function(fn, scope, o, caller, manager) { var me = this, namedScope = Ext._namedScopes[scope], listener = { fn: fn, scope: scope, ev: me, caller: caller, manager: manager, namedScope: namedScope, defaultScope: namedScope ? (scope || me.observable) : undefined, lateBound: typeof fn === 'string' }, handler = fn, wrapped = false, type; if (o) { listener.o = o; if (o.single) { handler = me.createSingle(handler, listener, o, scope); wrapped = true; } if (o.target) { handler = me.createTargeted(handler, listener, o, scope, wrapped); wrapped = true; } if (o.delay) { handler = me.createDelayed(handler, listener, o, scope, wrapped); wrapped = true; } if (o.buffer) { handler = me.createBuffered(handler, listener, o, scope, wrapped); wrapped = true; } if (me.observable.isElement) { type = o.type; if (type) { listener.type = type; } } } listener.fireFn = handler; listener.wrapped = wrapped; return listener; }, findListener: function(fn, scope) { var listeners = this.listeners, i = listeners.length, listener; while (i--) { listener = listeners[i]; if (listener) { if (listener.fn === fn && listener.scope == scope) { return i; } } } return -1; }, removeListener: function(fn, scope, index) { var me = this, removed = false, observable = me.observable, eventName = me.name, listener, highestNegativePriorityIndex, options, k, manager, managedListeners, managedListener, i; index = index || me.findListener(fn, scope); if (index != -1) { listener = me.listeners[index]; options = listener.o; highestNegativePriorityIndex = me._highestNegativePriorityIndex; 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); manager = listener.manager; if (manager) { managedListeners = manager.managedListeners; if (managedListeners) { for (i = managedListeners.length; i--; ) { managedListener = managedListeners[i]; if (managedListener.item === me.observable && managedListener.ename === eventName && managedListener.fn === fn && managedListener.scope === scope) { managedListeners.splice(i, 1); } } } } if (highestNegativePriorityIndex) { if (index < highestNegativePriorityIndex) { me._highestNegativePriorityIndex--; } else if (index === highestNegativePriorityIndex && index === me.listeners.length) { delete me._highestNegativePriorityIndex; } } if (observable.isElement) { observable._getPublisher(eventName).unsubscribe(observable, eventName, options.delegated !== false, options.capture); } removed = true; } return removed; }, clearListeners: function() { var listeners = this.listeners, i = listeners.length, listener; while (i--) { listener = listeners[i]; this.removeListener(listener.fn, listener.scope); } }, suspend: function() { ++this.suspended; }, resume: function() { if (this.suspended) { --this.suspended; } }, isSuspended: function() { return this.suspended > 0; }, fire: function() { var me = this, listeners = me.listeners, count = listeners.length, isElement = me.observable.isElement, options, delegate, fireInfo, i, args, listener, len, delegateEl, currentTarget, type, chained, firingArgs, e; if (!me.suspended && count > 0) { me.firing = true; args = arguments.length ? arraySlice.call(arguments, 0) : []; len = args.length; if (isElement) { e = args[0]; } for (i = 0; i < count; i++) { listener = listeners[i]; options = listener.o; if (isElement) { if (currentTarget) { e.setCurrentTarget(currentTarget); } type = listener.type; if (type) { chained = e; e = args[0] = chained.chain({ type: type }); } Ext.EventObject = e; } firingArgs = args; if (options) { if (isElement) { delegate = options.delegate; if (delegate) { delegateEl = e.getTarget('#' + e.currentTarget.id + ' ' + delegate); if (delegateEl) { args[1] = delegateEl; currentTarget = e.currentTarget; e.setCurrentTarget(delegateEl); } else { continue; } } if (options.preventDefault) { e.preventDefault(); } if (options.stopPropagation) { e.stopPropagation(); } if (options.stopEvent) { e.stopEvent(); } } args[len] = options; if (options.args) { firingArgs = options.args.concat(args); } } fireInfo = me.getFireInfo(listener); if (fireInfo.fn.apply(fireInfo.scope, firingArgs) === false) { return (me.firing = false); } if (chained) { e = args[0] = chained; chained = null; } } } me.firing = false; return true; }, getFireInfo: function(listener, fromWrapped) { var observable = this.observable, fireFn = listener.fireFn, scope = listener.scope, namedScope = listener.namedScope, fn; if (!fromWrapped && listener.wrapped) { fireArgs.fn = fireFn; return fireArgs; } fn = fromWrapped ? listener.fn : fireFn; var name = fn; if (listener.lateBound) { if (!scope || namedScope) { scope = (listener.caller || observable).resolveListenerScope(listener.defaultScope); } if (!scope) { Ext.Error.raise('Unable to dynamically resolve scope for "' + listener.ev.name + '" listener on ' + this.observable.id); } if (!Ext.isFunction(scope[fn])) { Ext.Error.raise('No method named "' + fn + '" on ' + (scope.$className || 'scope object.')); } fn = scope[fn]; } else if (namedScope && namedScope.isController) { scope = (listener.caller || observable).resolveListenerScope(listener.defaultScope); if (!scope) { Ext.Error.raise('Unable to dynamically resolve scope for "' + listener.ev.name + '" listener on ' + this.observable.id); } } else if (!scope || namedScope) { scope = observable; } fireArgs.fn = fn; fireArgs.scope = scope; if (!fn) { Ext.Error.raise('Unable to dynamically resolve method "' + name + '" on ' + this.observable.$className); } return fireArgs; }, createTargeted: function(handler, listener, o, scope, wrapped) { return function() { if (o.target === arguments[0]) { var fireInfo; if (!wrapped) { fireInfo = listener.ev.getFireInfo(listener, true); handler = fireInfo.fn; scope = fireInfo.scope; } return handler.apply(scope, arguments); } }; }, createBuffered: function(handler, listener, o, scope, wrapped) { listener.task = new Ext.util.DelayedTask(); return function() { var fireInfo; if (!wrapped) { fireInfo = listener.ev.getFireInfo(listener, true); handler = fireInfo.fn; scope = fireInfo.scope; } listener.task.delay(o.buffer, handler, scope, toArray(arguments)); }; }, createDelayed: function(handler, listener, o, scope, wrapped) { return function() { var task = new Ext.util.DelayedTask(), fireInfo; if (!wrapped) { fireInfo = listener.ev.getFireInfo(listener, true); handler = fireInfo.fn; scope = fireInfo.scope; } if (!listener.tasks) { listener.tasks = []; } listener.tasks.push(task); task.delay(o.delay || 10, handler, scope, toArray(arguments)); }; }, createSingle: function(handler, listener, o, scope, wrapped) { return function() { var event = listener.ev, fireInfo; if (event.removeListener(listener.fn, scope) && event.observable) { event.observable.hasListeners[event.name]--; } if (!wrapped) { fireInfo = event.getFireInfo(listener, true); handler = fireInfo.fn; scope = fireInfo.scope; } return handler.apply(scope, arguments); }; } }; }); //@tag dom,core Ext.define('Ext.mixin.Identifiable', { statics: { uniqueIds: {} }, isIdentifiable: true, mixinId: 'identifiable', idCleanRegex: /\.|[^\w\-]/g, defaultIdPrefix: 'ext-', defaultIdSeparator: '-', getOptimizedId: function() { return this.id; }, getUniqueId: function() { var id = this.id, prototype, separator, xtype, uniqueIds, prefix; if (!(id || id === 0)) { prototype = this.self.prototype; separator = this.defaultIdSeparator; uniqueIds = Ext.mixin.Identifiable.uniqueIds; if (!prototype.hasOwnProperty('identifiablePrefix')) { xtype = this.xtype; if (xtype) { prefix = this.defaultIdPrefix + xtype.replace(this.idCleanRegex, separator) + separator; } else if (!(prefix = prototype.$className)) { prefix = this.defaultIdPrefix + 'anonymous' + separator; } else { prefix = prefix.replace(this.idCleanRegex, separator).toLowerCase() + separator; } prototype.identifiablePrefix = prefix; } prefix = this.identifiablePrefix; if (!uniqueIds.hasOwnProperty(prefix)) { uniqueIds[prefix] = 0; } id = this.id = prefix + (++uniqueIds[prefix]); } this.getUniqueId = this.getOptimizedId; return id; }, setId: function(id) { this.id = id; }, getId: function() { var id = this.id; if (!id) { id = this.getUniqueId(); } this.getId = this.getOptimizedId; return id; } }); Ext.define('Ext.mixin.Observable', function(Observable) { var emptyFn = Ext.emptyFn, emptyArray = [], arrayProto = Array.prototype, arraySlice = arrayProto.slice, ListenerRemover = function(observable) { if (observable instanceof ListenerRemover) { return observable; } this.observable = observable; if (arguments[1].isObservable) { this.managedListeners = true; } this.args = arraySlice.call(arguments, 1); }; ListenerRemover.prototype.destroy = function() { this.destroy = Ext.emptyFn; var observable = this.observable; observable[this.managedListeners ? 'mun' : 'un'].apply(observable, this.args); }; return { extend: 'Ext.Mixin', mixinConfig: { id: 'observable', after: { destroy: 'clearListeners' } }, requires: [ 'Ext.util.Event' ], mixins: [ 'Ext.mixin.Identifiable' ], statics: { releaseCapture: function(o) { o.fireEventArgs = this.prototype.fireEventArgs; }, capture: function(o, fn, scope) { var newFn = function(eventName, args) { return fn.apply(scope, [ eventName ].concat(args)); }; this.captureArgs(o, newFn, scope); }, captureArgs: function(o, fn, scope) { o.fireEventArgs = Ext.Function.createInterceptor(o.fireEventArgs, fn, scope); }, observe: function(cls, listeners) { if (cls) { if (!cls.isObservable) { Ext.applyIf(cls, new this()); this.captureArgs(cls.prototype, cls.fireEventArgs, cls); } if (Ext.isObject(listeners)) { cls.on(listeners); } } return cls; }, prepareClass: function(T, mixin, data) { var listeners = T.listeners = [], target = data || T.prototype, targetListeners = target.listeners, superListeners = mixin ? mixin.listeners : T.superclass.self.listeners, name, scope, namedScope; if (superListeners) { listeners.push(superListeners); } if (targetListeners) { scope = targetListeners.scope; if (!scope) { targetListeners.scope = 'self'; } else { namedScope = Ext._namedScopes[scope]; if (namedScope && namedScope.isController) { targetListeners.scope = 'self.controller'; } } listeners.push(targetListeners); target.listeners = null; } if (!T.HasListeners) { var HasListeners = function() {}, SuperHL = T.superclass.HasListeners || (mixin && mixin.HasListeners) || Observable.HasListeners; T.prototype.HasListeners = T.HasListeners = HasListeners; HasListeners.prototype = T.hasListeners = new SuperHL(); } } }, isObservable: true, eventsSuspended: 0, constructor: function(config) { var me = this, self = me.self, declaredListeners, listeners, bubbleEvents, len, i; if (me.$observableInitialized) { return; } me.$observableInitialized = true; me.hasListeners = new me.HasListeners(); me.events = me.events || {}; declaredListeners = self.listeners; if (declaredListeners && !me._addDeclaredListeners(declaredListeners)) { self.listeners = null; } listeners = (config && config.listeners) || me.listeners; if (listeners) { if (listeners instanceof Array) { for (i = 0 , len = listeners.length; i < len; ++i) { me.addListener(listeners[i]); } } else { me.addListener(listeners); } } bubbleEvents = (config && config.bubbleEvents) || me.bubbleEvents; if (bubbleEvents) { me.enableBubble(bubbleEvents); } if (me.$applyConfigs) { Ext.apply(me, config); } else { me.initConfig(config); } if (listeners) { me.listeners = null; } }, onClassExtended: function(T, data) { if (!T.HasListeners) { Observable.prepareClass(T, T.prototype.$observableMixedIn ? undefined : data); } }, $eventOptions: { scope: 1, delay: 1, buffer: 1, onFrame: 1, single: 1, args: 1, destroyable: 1, priority: 1, order: 1 }, $orderToPriority: { before: 100, current: 0, after: -100 }, _addDeclaredListeners: function(listeners) { var me = this; if (listeners instanceof Array) { Ext.each(listeners, me._addDeclaredListeners, me); } else { me._addedDeclaredListeners = true; me.addListener(listeners); } return me._addedDeclaredListeners; }, addManagedListener: function(item, ename, fn, scope, options, noDestroy) { var me = this, managedListeners = me.managedListeners = me.managedListeners || [], config, passedOptions; if (typeof ename !== 'string') { passedOptions = arguments.length > 4 ? options : ename; options = ename; for (ename in options) { if (options.hasOwnProperty(ename)) { config = options[ename]; if (!item.$eventOptions[ename]) { me.addManagedListener(item, ename, config.fn || config, config.scope || options.scope || scope, config.fn ? config : passedOptions, true); } } } if (options && options.destroyable) { return new ListenerRemover(me, item, options); } } else { if (fn !== emptyFn) { item.doAddListener(ename, fn, scope, options, null, me, me); if (!noDestroy && options && options.destroyable) { return new ListenerRemover(me, item, ename, fn, scope); } } } }, removeManagedListener: function(item, ename, fn, scope) { var me = this, options, config, managedListeners, length, i; if (typeof ename !== 'string') { options = ename; for (ename in options) { if (options.hasOwnProperty(ename)) { config = options[ename]; if (!item.$eventOptions[ename]) { me.removeManagedListener(item, ename, config.fn || config, config.scope || options.scope || scope); } } } } else { managedListeners = me.managedListeners ? me.managedListeners.slice() : []; ename = Ext.canonicalEventName(ename); for (i = 0 , length = managedListeners.length; i < length; i++) { me.removeManagedListenerItem(false, managedListeners[i], item, ename, fn, scope); } } }, fireEvent: function(eventName) { return this.fireEventArgs(eventName, arraySlice.call(arguments, 1)); }, resolveListenerScope: function(defaultScope) { var namedScope = Ext._namedScopes[defaultScope]; if (namedScope) { if (namedScope.isController) { Ext.Error.raise('scope: "controller" can only be specified on classes that derive from Ext.Component or Ext.Widget'); } if (namedScope.isSelf || namedScope.isThis) { defaultScope = null; } } return defaultScope || this; }, fireEventArgs: function(eventName, args) { eventName = Ext.canonicalEventName(eventName); var me = this, events = me.events, event = events && events[eventName], ret = true; if (me.hasListeners[eventName]) { ret = me.doFireEvent(eventName, args || emptyArray, event ? event.bubble : false); } return ret; }, fireAction: function(eventName, args, fn, scope, options, order) { options = options ? Ext.Object.chain(options) : {}; options.single = true; options.priority = ((order === 'after') ? -99.5 : 99.5); this.doAddListener(eventName, fn, scope, options); this.fireEventArgs(eventName, args); }, doFireEvent: function(eventName, args, bubbles) { var target = this, queue, event, ret = true; do { if (target.eventsSuspended) { if ((queue = target.eventQueue)) { queue.push([ eventName, args ]); } return ret; } else { event = target.events && target.events[eventName]; if (event && event !== true) { if ((ret = event.fire.apply(event, args)) === false) { break; } } } } while ( bubbles && (target = target.getBubbleParent())); return ret; }, getBubbleParent: function() { var me = this, parent = me.getBubbleTarget && me.getBubbleTarget(); if (parent && parent.isObservable) { return parent; } return null; }, addListener: function(ename, fn, scope, options, order, caller) { var me = this, namedScopes = Ext._namedScopes, config, namedScope, isClassListener, innerScope, eventOptions; if (typeof ename !== 'string') { options = ename; scope = options.scope; namedScope = scope && namedScopes[scope]; isClassListener = namedScope && namedScope.isSelf; eventOptions = ((me.isComponent || me.isWidget) && options.element) ? me.$elementEventOptions : me.$eventOptions; for (ename in options) { config = options[ename]; if (!eventOptions[ename]) { innerScope = config.scope; if (innerScope && isClassListener) { namedScope = namedScopes[innerScope]; if (namedScope && namedScope.isController) { innerScope = 'self.controller'; } } me.doAddListener(ename, config.fn || config, innerScope || scope, config.fn ? config : options, order, caller); } } if (options && options.destroyable) { return new ListenerRemover(me, options); } } else { me.doAddListener(ename, fn, scope, options, order, caller); if (options && options.destroyable) { return new ListenerRemover(me, ename, fn, scope, options); } } return me; }, removeListener: function(ename, fn, scope, eventOptions) { var me = this, config, options; if (typeof ename !== 'string') { options = ename; eventOptions = eventOptions || me.$eventOptions; for (ename in options) { if (options.hasOwnProperty(ename)) { config = options[ename]; if (!me.$eventOptions[ename]) { me.doRemoveListener(ename, config.fn || config, config.scope || options.scope); } } } } else { me.doRemoveListener(ename, fn, scope); } return me; }, clearListeners: function() { var me = this, events = me.events, hasListeners = me.hasListeners, event, key; if (events) { for (key in events) { if (events.hasOwnProperty(key)) { event = events[key]; if (event.isEvent) { delete hasListeners[key]; event.clearListeners(); } } } } me.clearManagedListeners(); }, purgeListeners: function() { if (Ext.global.console) { Ext.global.console.warn('Observable: purgeListeners has been deprecated. Please use clearListeners.'); } return this.clearListeners.apply(this, arguments); }, clearManagedListeners: function() { var me = this, managedListeners = me.managedListeners ? me.managedListeners.slice() : [], i = 0, len = managedListeners.length; for (; i < len; i++) { me.removeManagedListenerItem(true, managedListeners[i]); } me.managedListeners = []; }, removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope) { if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) { managedListener.item.doRemoveListener(managedListener.ename, managedListener.fn, managedListener.scope, managedListener.options); if (!isClear) { Ext.Array.remove(this.managedListeners, managedListener); } } }, purgeManagedListeners: function() { if (Ext.global.console) { Ext.global.console.warn('Observable: purgeManagedListeners has been deprecated. Please use clearManagedListeners.'); } return this.clearManagedListeners.apply(this, arguments); }, hasListener: function(ename) { ename = Ext.canonicalEventName(ename); return !!this.hasListeners[ename]; }, isSuspended: function(event) { var suspended = this.eventsSuspended > 0, events = this.events; if (!suspended && event && events) { event = events[event]; if (event && event.isEvent) { return event.isSuspended(); } } return suspended; }, suspendEvents: function(queueSuspended) { ++this.eventsSuspended; if (queueSuspended && !this.eventQueue) { this.eventQueue = []; } }, suspendEvent: function() { var me = this, events = me.events, len = arguments.length, i, event, ename; for (i = 0; i < len; i++) { ename = arguments[i]; ename = Ext.canonicalEventName(ename); event = events[ename]; if (!event || !event.isEvent) { event = me._initEvent(ename); } event.suspend(); } }, resumeEvent: function() { var events = this.events || 0, len = events && arguments.length, i, event; for (i = 0; i < len; i++) { event = events[arguments[i]]; if (event && event.resume) { event.resume(); } } }, resumeEvents: function(discardQueue) { var me = this, queued = me.eventQueue, qLen, q; if (me.eventsSuspended && !--me.eventsSuspended) { delete me.eventQueue; if (!discardQueue && queued) { qLen = queued.length; for (q = 0; q < qLen; q++) { me.fireEventArgs.apply(me, queued[q]); } } } }, relayEvents: function(origin, events, prefix) { var me = this, len = events.length, i = 0, oldName, relayers = {}; for (; i < len; i++) { oldName = events[i]; relayers[oldName] = me.createRelayer(prefix ? prefix + oldName : oldName); } me.mon(origin, relayers, null, null, undefined); return new ListenerRemover(me, origin, relayers); }, createRelayer: function(newName, beginEnd) { var me = this; return function() { return me.fireEventArgs.call(me, newName, beginEnd ? arraySlice.apply(arguments, beginEnd) : arguments); }; }, enableBubble: function(eventNames) { if (eventNames) { var me = this, names = (typeof eventNames == 'string') ? arguments : eventNames, events = me.events, length = events && names.length, ename, event, i; for (i = 0; i < length; ++i) { ename = names[i]; ename = Ext.canonicalEventName(ename); event = events[ename]; if (!event || !event.isEvent) { event = me._initEvent(ename); } me.hasListeners._incr_(ename); event.bubble = true; } } }, destroy: function() { this.clearListeners(); this.callParent(); }, privates: { doAddListener: function(ename, fn, scope, options, order, caller, manager) { var me = this, event, managedListeners, priority; order = order || (options && options.order); if (order) { priority = (options && options.priority); if (!priority) { options = options ? Ext.Object.chain(options) : {}; options.priority = me.$orderToPriority[order]; } } ename = Ext.canonicalEventName(ename); if (!fn) { Ext.Error.raise("Cannot add '" + ename + "' listener to " + me.$className + " instance. No function specified."); } if (!manager && (scope && scope.isObservable && (scope !== me))) { manager = scope; } if (manager) { managedListeners = manager.managedListeners = manager.managedListeners || []; managedListeners.push({ item: me, ename: ename, fn: fn, scope: scope, options: options }); } event = (me.events || (me.events = {}))[ename]; if (!event || !event.isEvent) { event = me._initEvent(ename); } if (fn !== emptyFn) { if (event.addListener(fn, scope, options, caller, manager)) { me.hasListeners._incr_(ename); } } }, doRemoveListener: function(ename, fn, scope) { var me = this, events = me.events, event; ename = Ext.canonicalEventName(ename); event = events && events[ename]; if (!fn) { Ext.Error.raise("Cannot remove '" + ename + "' listener to " + me.$className + " instance. No function specified."); } if (event && event.isEvent) { if (event.removeListener(fn, scope)) { me.hasListeners._decr_(ename); } } }, _initEvent: function(eventName) { return (this.events[eventName] = new Ext.util.Event(this, eventName)); } }, deprecated: { '5.0': { methods: { addEvents: null } }, '5.1': { methods: { addBeforeListener: function(eventName, fn, scope, options) { return this.addListener(eventName, fn, scope, options, 'before'); }, addAfterListener: function(eventName, fn, scope, options) { return this.addListener(eventName, fn, scope, options, 'after'); }, removeBeforeListener: function(eventName, fn, scope, options) { return this.removeListener(eventName, fn, scope, options, 'before'); }, removeAfterListener: function(eventName, fn, scope, options) { return this.removeListener(eventName, fn, scope, options, 'after'); }, onBefore: 'addBeforeListener', onAfter: 'addAfterListener', unBefore: 'removeBeforeListener', unAfter: 'removeAfterListener' } } } }; }, function() { var Observable = this, proto = Observable.prototype, HasListeners = function() {}, prepareMixin = function(T) { if (!T.HasListeners) { var proto = T.prototype; proto.$observableMixedIn = 1; Observable.prepareClass(T, this); T.onExtended(function(U, data) { Ext.classSystemMonitor && Ext.classSystemMonitor('extend mixin', arguments); Observable.prepareClass(U, null, data); }); if (proto.onClassMixedIn) { Ext.override(T, { onClassMixedIn: function(U) { prepareMixin.call(this, U); this.callParent(arguments); } }); } else { proto.onClassMixedIn = function(U) { prepareMixin.call(this, U); }; } } superOnClassMixedIn.call(this, T); }, superOnClassMixedIn = proto.onClassMixedIn; HasListeners.prototype = { _decr_: function(ev) { if (!--this[ev]) { delete this[ev]; } }, _incr_: function(ev) { if (this.hasOwnProperty(ev)) { ++this[ev]; } else { this[ev] = 1; } } }; proto.HasListeners = Observable.HasListeners = HasListeners; Observable.createAlias({ on: 'addListener', un: 'removeListener', mon: 'addManagedListener', mun: 'removeManagedListener', setListeners: 'addListener' }); Observable.observeClass = Observable.observe; function getMethodEvent(method) { var e = (this.methodEvents = this.methodEvents || {})[method], returnValue, v, cancel, obj = this, makeCall; if (!e) { this.methodEvents[method] = e = {}; e.originalFn = this[method]; e.methodName = method; e.before = []; e.after = []; 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; } Ext.apply(proto, { onClassMixedIn: prepareMixin, 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) { Ext.Array.erase(e.before, i, 1); return; } } for (i = 0 , len = e.after.length; i < len; i++) { if (e.after[i].fn == fn && e.after[i].scope == scope) { Ext.Array.erase(e.after, 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.HashMap', { mixins: [ 'Ext.mixin.Observable' ], generation: 0, config: { keyFn: null }, constructor: function(config) { var me = this, fn; me.mixins.observable.constructor.call(me, config); me.clear(true); fn = me.getKeyFn(); if (fn) { me.getKey = fn; } }, 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; if (arguments.length === 1) { value = key; key = me.getKey(value); } if (me.containsKey(key)) { return me.replace(key, value); } me.map[key] = value; ++me.length; me.generation++; if (me.hasListeners.add) { me.fireEvent('add', me, key, value); } return value; }, replace: function(key, value) { var me = this, map = me.map, old; if (arguments.length === 1) { value = key; key = me.getKey(value); } if (!me.containsKey(key)) { me.add(key, value); } old = map[key]; map[key] = value; me.generation++; if (me.hasListeners.replace) { 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.generation++; if (me.hasListeners.remove) { me.fireEvent('remove', me, key, value); } return true; } return false; }, get: function(key) { var map = this.map; return map.hasOwnProperty(key) ? map[key] : undefined; }, clear: function( initial) { var me = this; if (initial || me.generation) { me.map = {}; me.length = 0; me.generation = initial ? 0 : me.generation + 1; } if (initial !== true && me.hasListeners.clear) { me.fireEvent('clear', me); } return me; }, containsKey: function(key) { var map = this.map; return map.hasOwnProperty(key) && 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(this.initialConfig), 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.AbstractManager', { requires: [ 'Ext.util.HashMap' ], typeName: 'type', constructor: function(config) { Ext.apply(this, config || {}); this.all = new Ext.util.HashMap(); this.types = {}; }, get: function(id) { return this.all.get(id); }, register: function(item) { var key = this.all.getKey(item); if (key === undefined) { Ext.Error.raise('Key is undefined. Please ensure the item has a key before registering the item.'); } if (this.all.containsKey(key)) { Ext.Error.raise('Registering duplicate id "' + key + '" with ' + this.$className); } this.all.add(item); }, unregister: function(item) { this.all.remove(item); }, registerType: function(type, cls) { this.types[type] = cls; cls[this.typeName] = type; }, isRegistered: function(type) { return this.types[type] !== undefined; }, 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); }, onAvailable: function(id, fn, scope) { var all = this.all, item, callback; if (all.containsKey(id)) { item = all.get(id); fn.call(scope || item, item); } else { callback = function(map, key, item) { if (key == id) { fn.call(scope || item, item); all.un('add', callback); } }; all.on('add', callback); } }, each: function(fn, scope) { this.all.each(fn, scope || this); }, getCount: function() { return this.all.getCount(); } }); Ext.define('Ext.data.flash.BinaryXhr', { statics: { flashPluginActivated: function() { Ext.data.flash.BinaryXhr.flashPluginActive = true; Ext.data.flash.BinaryXhr.flashPlugin = document.getElementById("ext-flash-polyfill"); Ext.GlobalEvents.fireEvent("flashready"); }, flashPluginActive: false, flashPluginInjected: false, connectionIndex: 1, liveConnections: {}, flashPlugin: null, onFlashStateChange: function(javascriptId, state, data) { var connection; connection = this.liveConnections[Number(javascriptId)]; if (connection) { connection.onFlashStateChange(state, data); } else { Ext.warn.log("onFlashStateChange for unknown connection ID: " + javascriptId); } }, registerConnection: function(conn) { var i = this.connectionIndex; this.conectionIndex = this.connectionIndex + 1; this.liveConnections[i] = conn; return i; }, injectFlashPlugin: function() { var me = this, flashLoaderPath, flashObjectPath; me.flashPolyfillEl = Ext.getBody().appendChild({ id: 'ext-flash-polyfill', cn: [ { tag: 'p', html: 'To view this page ensure that Adobe Flash Player version 11.1.0 or greater is installed.' }, { tag: 'a', href: 'http://www.adobe.com/go/getflashplayer', cn: [ { tag: 'img', src: window.location.protocol + '//www.adobe.com/images/shared/download_buttons/get_flash_player.gif', alt: 'Get Adobe Flash player' } ] } ] }); flashLoaderPath = [ Ext.Loader.getPath('Ext.data.Connection'), '../../../plugins/flash/swfobject.js' ].join('/'); flashObjectPath = "/plugins/flash/FlashPlugin.swf"; flashObjectPath = [ Ext.Loader.getPath('Ext.data.Connection'), '../../plugins/flash/FlashPlugin.swf' ].join('/'); if (Ext.flashPluginPath) { flashObjectPath = Ext.flashPluginPath; } Ext.Loader.loadScript({ url: flashLoaderPath, onLoad: function() { var swfVersionStr = "11.4.0"; var xiSwfUrlStr = "playerProductInstall.swf"; var flashvars = {}; var params = {}; params.quality = "high"; params.bgcolor = "#ffffff"; params.allowscriptaccess = "sameDomain"; params.allowfullscreen = "true"; var attributes = {}; attributes.id = "ext-flash-polyfill"; attributes.name = "polyfill"; attributes.align = "middle"; swfobject.embedSWF(flashObjectPath, "ext-flash-polyfill", "0", "0", swfVersionStr, xiSwfUrlStr, flashvars, params, attributes); }, onError: function() { Ext.Error.raise("Could not load flash-loader file swfobject.js from " + flashLoader); }, scope: me }); Ext.data.flash.BinaryXhr.flashPluginInjected = true; } }, readyState: 0, status: 0, statusText: "", responseBytes: null, javascriptId: null, constructor: function(config) { if (!Ext.data.flash.BinaryXhr.flashPluginInjected) { Ext.data.flash.BinaryXhr.injectFlashPlugin(); } var me = this; Ext.apply(me, config); me.requestHeaders = {}; }, abort: function() { var me = this; if (me.readyState == 4) { Ext.warn.log("Aborting a connection that's completed its transfer: " + this.url); return; } me.aborted = true; if (!Ext.data.flash.BinaryXhr.flashPluginActive) { Ext.GlobalEvents.removeListener("flashready", me.onFlashReady, me); return; } Ext.data.flash.BinaryXhr.flashPlugin.abortRequest(me.javascriptId); delete Ext.data.flash.BinaryXhr.liveConnections[me.javascriptId]; }, getAllResponseHeaders: function() { var headers = []; Ext.Object.each(this.responseHeaders, function(name, value) { headers.push(name + ': ' + value); }); return headers.join('\r\n'); }, getResponseHeader: function(header) { var headers = this.responseHeaders; return (headers && headers[header]) || null; }, open: function(method, url, async, user, password) { var me = this; me.method = method; me.url = url; me.async = async !== false; me.user = user; me.password = password; if (!me.async) { Ext.Error.raise("Binary posts are only supported in async mode: " + url); } if (me.method != "POST") { Ext.log.warn("Binary data can only be sent as a POST request: " + url); } }, overrideMimeType: function(mimeType) { this.mimeType = mimeType; }, send: function(body) { var me = this; me.body = body; if (!Ext.data.flash.BinaryXhr.flashPluginActive) { Ext.GlobalEvents.addListener("flashready", me.onFlashReady, me); } else { this.onFlashReady(); } }, onFlashReady: function() { var me = this, req, status; me.javascriptId = Ext.data.flash.BinaryXhr.registerConnection(me); req = { method: me.method, url: me.url, user: me.user, password: me.password, mimeType: me.mimeType, requestHeaders: me.requestHeaders, body: me.body, javascriptId: me.javascriptId }; status = Ext.data.flash.BinaryXhr.flashPlugin.postBinary(req); }, setReadyState: function(state) { var me = this; if (me.readyState != state) { me.readyState = state; me.onreadystatechange(); } }, setRequestHeader: function(header, value) { this.requestHeaders[header] = value; }, onreadystatechange: Ext.emptyFn, parseData: function(data) { var me = this; this.status = data.status || 0; me.responseHeaders = {}; if (me.mimeType) { me.responseHeaders["content-type"] = me.mimeType; } if (data.reason == "complete") { this.responseBytes = data.data; me.responseHeaders["content-length"] = data.data.length; } else if (data.reason == "error" || data.reason == "securityError") { this.statusText = data.text; me.responseHeaders["content-length"] = 0; } else { Ext.Error.raise("Unkown reason code in data: " + data.reason); } }, onFlashStateChange: function(state, data) { var me = this; if (state == 4) { me.parseData(data); delete Ext.data.flash.BinaryXhr.liveConnections[me.javascriptId]; } me.setReadyState(state); } }); Ext.define('Ext.data.Connection', { mixins: { observable: 'Ext.mixin.Observable' }, requires: [ 'Ext.data.flash.BinaryXhr' ], statics: { requestId: 0 }, config: { url: null, async: true, username: '', password: '', disableCaching: true, withCredentials: false, binary: false, cors: false, isXdr: false, defaultXdrContentType: 'text/plain', disableCachingParam: '_dc', timeout: 30000, extraParams: null, autoAbort: false, method: null, defaultHeaders: null, defaultPostHeader: 'application/x-www-form-urlencoded; charset=UTF-8', useDefaultXhrHeader: true, defaultXhrHeader: 'XMLHttpRequest' }, constructor: function(config) { this.mixins.observable.constructor.call(this, config); this.requests = {}; }, request: function(options) { options = options || {}; var me = this, scope = options.scope || window, username = options.username || me.getUsername(), password = options.password || me.getPassword() || '', async, requestOptions, request, headers, xdr, xhr; if (me.fireEvent('beforerequest', me, options) !== false) { requestOptions = me.setOptions(options, scope); if (me.isFormUpload(options)) { me.upload(options.form, requestOptions.url, requestOptions.data, options); return null; } if (options.autoAbort || me.getAutoAbort()) { me.abort(); } async = options.async !== false ? (options.async || me.getAsync()) : false; xhr = me.openRequest(options, requestOptions, async, username, password); xdr = me.getIsXdr(); if (!xdr) { headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params); } request = { id: ++Ext.data.Connection.requestId, xhr: xhr, headers: headers, options: options, async: async, binary: options.binary || me.getBinary(), timeout: Ext.defer(function() { request.timedout = true; me.abort(request); }, options.timeout || me.getTimeout()) }; me.requests[request.id] = request; me.latestId = request.id; if (async) { if (!xdr) { xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [ request ]); } } if (xdr) { me.processXdrRequest(request, xhr); } xhr.send(requestOptions.data); if (!async) { return me.onComplete(request); } return request; } else { Ext.callback(options.callback, options.scope, [ options, undefined, undefined ]); return null; } }, processXdrRequest: function(request, xhr) { var me = this; delete request.headers; request.contentType = request.options.contentType || me.getDefaultXdrContentType(); xhr.onload = Ext.Function.bind(me.onStateChange, me, [ request, true ]); xhr.onerror = xhr.ontimeout = Ext.Function.bind(me.onStateChange, me, [ request, false ]); }, processXdrResponse: function(response, xhr) { response.getAllResponseHeaders = function() { return []; }; response.getResponseHeader = function() { return ''; }; response.contentType = xhr.contentType || this.getDefaultXdrContentType(); }, 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 }, addField = function(name, value) { hiddenItem = document.createElement('input'); Ext.fly(hiddenItem).set({ type: 'hidden', value: value, name: name }); form.appendChild(hiddenItem); hiddens.push(hiddenItem); }, hiddenItem, obj, value, name, vLen, v, hLen, h; Ext.fly(frame).set({ id: id, name: id, cls: Ext.baseCSSPrefix + 'hidden-display', src: Ext.SSL_SECURE_URL, tabIndex: -1 }); 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) { obj = Ext.Object.fromQueryString(params) || {}; for (name in obj) { if (obj.hasOwnProperty(name)) { value = obj[name]; if (Ext.isArray(value)) { vLen = value.length; for (v = 0; v < vLen; v++) { addField(name, value[v]); } } else { addField(name, value); } } } } Ext.get(frame).on({ load: Ext.Function.bind(this.onUploadComplete, this, [ frame, options ]), single: !Ext.isOpera }); form.submit(); Ext.fly(form).set(buf); for (hLen = hiddens.length , h = 0; h < hLen; h++) { Ext.removeNode(hiddens[h]); } }, onUploadComplete: function(frame, options) { var me = this, response = { responseText: '', responseXML: null }, callback, success, doc, contentNode; try { doc = (frame && (frame.contentWindow.document || frame.contentDocument)) || (window.frames[frame.id] || {}).document; if (doc) { if (Ext.isOpera && doc.location == Ext.SSL_SECURE_URL) { return; } if (doc.body) { if ((contentNode = doc.body.firstChild) && /pre/i.test(contentNode.tagName)) { response.responseText = contentNode.textContent || contentNode.innerText; } else if ((contentNode = doc.getElementsByTagName('textarea')[0])) { response.responseText = contentNode.value; } else { response.responseText = doc.body.textContent || doc.body.innerText; } } response.responseXML = doc.XMLDocument || doc; callback = options.success; success = true; } else { Ext.Error.raise("Could not acquire a suitable connection for the file upload service."); } } catch (e) { response.responseText = '{success:false,message:"' + Ext.String.trim(e.message || e.description) + '"}'; callback = options.failure; success = false; } me.fireEvent(success ? 'requestcomplete' : 'requestexception', me, response, options); Ext.callback(callback, options.scope, [ response, options ]); Ext.callback(options.callback, options.scope, [ options, success, response ]); Ext.defer(Ext.removeNode, 100, Ext, [ frame ]); }, 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) { var form = options.form || null; if (form) { form = Ext.getDom(form); } return form; }, setOptions: function(options, scope) { var me = this, params = options.params || {}, extraParams = me.getExtraParams(), urlParams = options.urlParams, url = options.url || me.getUrl(), cors = options.cors, jsonData = options.jsonData, method, disableCache, data; if (cors !== undefined) { me.setCors(cors); } 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.binaryData || options.xmlData || jsonData || null; if (jsonData && !Ext.isPrimitive(jsonData)) { data = Ext.encode(data); } if (options.binaryData) { if (!Ext.isArray(options.binaryData)) { Ext.log.warn("Binary submission data must be an array of byte values! Instead got " + typeof (options.binaryData)); } if (me.nativeBinaryPostSupport()) { data = (new Uint8Array(options.binaryData)); if ((Ext.isChrome && Ext.chromeVersion < 22) || Ext.isSafari || Ext.isGecko) { data = data.buffer; } } } 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.getMethod() || ((params || data) ? 'POST' : 'GET')).toUpperCase(); this.setupMethod(options, method); disableCache = options.disableCaching !== false ? (options.disableCaching || me.getDisableCaching()) : false; if (method === 'GET' && disableCache) { url = Ext.urlAppend(url, (options.disableCachingParam || me.getDisableCachingParam()) + '=' + (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.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.getDefaultHeaders() || {}), contentType = me.getDefaultPostHeader(), jsonData = options.jsonData, xmlData = options.xmlData, type = 'Content-Type', useHeader = Ext.isDefined(options.useDefaultXhrHeader) ? options.useDefaultXhrHeader : me.getUseDefaultXhrHeader(), key, header; if (!headers.hasOwnProperty(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[type] = contentType; } if (useHeader && !headers['X-Requested-With']) { headers['X-Requested-With'] = me.getDefaultXhrHeader(); } if (headers[type] === undefined || headers[type] === null) { delete headers[type]; } 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; }, newRequest: function(options) { var me = this, xhr; if (options.binaryData) { if (me.nativeBinaryPostSupport()) { xhr = me.getXhrInstance(); } else { xhr = new Ext.data.flash.BinaryXhr(); } } else if (me.getCors() && Ext.isIE && Ext.ieVersion <= 9) { xhr = me.getXdrInstance(); me.setIsXdr(true); } else { xhr = me.getXhrInstance(); me.setIsXdr(false); } return xhr; }, openRequest: function(options, requestOptions, async, username, password) { var me = this, xhr = me.newRequest(options); if (username) { xhr.open(requestOptions.method, requestOptions.url, async, username, password); } else { if (me.getIsXdr()) { xhr.open(requestOptions.method, requestOptions.url); } else { xhr.open(requestOptions.method, requestOptions.url, async); } } if (options.binary || me.getBinary()) { if (window.Uint8Array) { xhr.responseType = 'arraybuffer'; } else if (xhr.overrideMimeType) { xhr.overrideMimeType('text/plain; charset=x-user-defined'); } else if (!Ext.isIE) { Ext.log.warn("Your browser does not support loading binary data using Ajax."); } } if (options.withCredentials || me.getWithCredentials()) { xhr.withCredentials = true; } return xhr; }, getXdrInstance: function() { var xdr; if (Ext.ieVersion >= 8) { xdr = new XDomainRequest(); } else { Ext.Error.raise({ msg: 'Your browser does not support CORS' }); } return xdr; }, 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 = this.getLatest(); } if (!(request && request.xhr)) { return false; } var state = request.xhr.readyState, Cls = Ext.data.flash && Ext.data.flash.BinaryXhr; return ((request.xhr instanceof Cls) && state != 4) || !(state === 0 || state == 4); }, abort: function(request) { var me = this, xhr; if (!request) { request = me.getLatest(); } if (request && me.isLoading(request)) { xhr = request.xhr; try { xhr.onreadystatechange = null; } catch (e) { xhr.onreadystatechange = Ext.emptyFn; } xhr.abort(); me.clearTimeout(request); if (!request.timedout) { request.aborted = true; } me.onComplete(request); me.cleanup(request); } }, abortAll: function() { var requests = this.requests, id; for (id in requests) { if (requests.hasOwnProperty(id)) { this.abort(requests[id]); } } }, getLatest: function() { var id = this.latestId, request; if (id) { request = this.requests[id]; } return request || null; }, onStateChange: function(request, xdrResult) { var me = this, globalEvents = Ext.GlobalEvents; if ((request.xhr && request.xhr.readyState == 4) || me.getIsXdr()) { me.clearTimeout(request); me.onComplete(request, xdrResult); me.cleanup(request); if (globalEvents.hasListeners.idle) { globalEvents.fireEvent('idle'); } } }, clearTimeout: function(request) { clearTimeout(request.timeout); delete request.timeout; }, cleanup: function(request) { request.xhr = null; delete request.xhr; }, onComplete: function(request, xdrResult) { var me = this, options = request.options, xhr, result, success, response; try { xhr = request.xhr; result = me.parseStatus(xhr.status); if (result.success) { result.success = xhr.readyState === 4; } } catch (e) { result = { success: false, isException: false }; } success = me.getIsXdr() ? xdrResult : result.success; if (success) { response = me.createResponse(request); me.fireEvent('requestcomplete', me, response, options); Ext.callback(options.success, options.scope, [ response, options ]); } else { if (result.isException || request.aborted || request.timedout) { response = me.createException(request); } else { response = me.createResponse(request); } me.fireEvent('requestexception', me, response, options); Ext.callback(options.failure, options.scope, [ response, options ]); } Ext.callback(options.callback, options.scope, [ options, success, response ]); delete me.requests[request.id]; return response; }, 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 me = this, xhr = request.xhr, isXdr = me.getIsXdr(), headers = {}, lines = isXdr ? [] : xhr.getAllResponseHeaders().replace(/\r\n/g, '\n').split('\n'), count = lines.length, line, index, key, response, byteArray; 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; } }; if (isXdr) { me.processXdrResponse(response, xhr); } if (request.binary) { response.responseBytes = me.getByteArray(xhr); } else { response.responseText = xhr.responseText; response.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 }; }, getByteArray: function(xhr) { var response = xhr.response, responseBody = xhr.responseBody, Cls = Ext.data.flash && Ext.data.flash.BinaryXhr, byteArray, responseText, len, i; if (xhr instanceof Cls) { byteArray = xhr.responseBytes; } else if (window.Uint8Array) { byteArray = response ? new Uint8Array(response) : []; } else if (Ext.isIE9p) { try { byteArray = new VBArray(responseBody).toArray(); } catch (e) { byteArray = []; } } else if (Ext.isIE) { if (!this.self.vbScriptInjected) { this.injectVBScript(); } getIEByteArray(xhr.responseBody, byteArray = []); } else { byteArray = []; responseText = xhr.responseText; len = responseText.length; for (i = 0; i < len; i++) { byteArray.push(responseText.charCodeAt(i) & 255); } } return byteArray; }, injectVBScript: function() { var scriptTag = document.createElement('script'); scriptTag.type = 'text/vbscript'; scriptTag.text = [ 'Function getIEByteArray(byteArray, out)', 'Dim len, i', 'len = LenB(byteArray)', 'For i = 1 to len', 'out.push(AscB(MidB(byteArray, i, 1)))', 'Next', 'End Function' ].join('\n'); Ext.getHead().dom.appendChild(scriptTag); this.self.vbScriptInjected = true; }, nativeBinaryPostSupport: function() { return Ext.isChrome || (Ext.isSafari && Ext.isDefined(window.Uint8Array)) || (Ext.isGecko && Ext.isDefined(window.Uint8Array)); } }); Ext.define('Ext.Ajax', { extend: 'Ext.data.Connection', singleton: true, autoAbort: false }); Ext.define('Ext.AnimationQueue', { singleton: true, constructor: function() { this.queue = []; this.taskQueue = []; this.runningQueue = []; this.idleQueue = []; this.isRunning = false; this.isIdle = true; this.run = Ext.Function.bind(this.run, this); if (Ext.os.is.iOS) { Ext.interval(this.watch, 500, this); } }, start: function(fn, scope, args) { this.queue.push(arguments); if (!this.isRunning) { if (this.hasOwnProperty('idleTimer')) { clearTimeout(this.idleTimer); delete this.idleTimer; } if (this.hasOwnProperty('idleQueueTimer')) { clearTimeout(this.idleQueueTimer); delete this.idleQueueTimer; } this.isIdle = false; this.isRunning = true; this.startCountTime = Ext.now(); this.count = 0; this.doStart(); } }, watch: function() { if (this.isRunning && Ext.now() - this.lastRunTime >= 500) { this.run(); } }, run: function() { if (!this.isRunning) { return; } var queue = this.runningQueue, i, ln; this.lastRunTime = Ext.now(); this.frameStartTime = Ext.now(); queue.push.apply(queue, this.queue); for (i = 0 , ln = queue.length; i < ln; i++) { this.invoke(queue[i]); } queue.length = 0; var now = this.frameStartTime, startCountTime = this.startCountTime, elapse = now - startCountTime, count = ++this.count; if (elapse >= 200) { this.onFpsChanged(count * 1000 / elapse, count, elapse); this.startCountTime = now; this.count = 0; } this.doIterate(); }, onFpsChanged: Ext.emptyFn, onStop: Ext.emptyFn, doStart: function() { this.animationFrameId = Ext.Function.requestAnimationFrame(this.run); this.lastRunTime = Ext.now(); }, doIterate: function() { this.animationFrameId = Ext.Function.requestAnimationFrame(this.run); }, doStop: function() { Ext.Function.cancelAnimationFrame(this.animationFrameId); }, stop: function(fn, scope, args) { if (!this.isRunning) { return; } var queue = this.queue, ln = queue.length, i, item; for (i = 0; i < ln; i++) { item = queue[i]; if (item[0] === fn && item[1] === scope && item[2] === args) { queue.splice(i, 1); i--; ln--; } } if (ln === 0) { this.doStop(); this.onStop(); this.isRunning = false; this.idleTimer = Ext.defer(this.whenIdle, 100, this); } }, onIdle: function(fn, scope, args) { var listeners = this.idleQueue, i, ln, listener; for (i = 0 , ln = listeners.length; i < ln; i++) { listener = listeners[i]; if (fn === listener[0] && scope === listener[1] && args === listener[2]) { return; } } listeners.push(arguments); if (this.isIdle) { this.processIdleQueue(); } }, unIdle: function(fn, scope, args) { var listeners = this.idleQueue, i, ln, listener; for (i = 0 , ln = listeners.length; i < ln; i++) { listener = listeners[i]; if (fn === listener[0] && scope === listener[1] && args === listener[2]) { listeners.splice(i, 1); return true; } } return false; }, queueTask: function(fn, scope, args) { this.taskQueue.push(arguments); this.processTaskQueue(); }, dequeueTask: function(fn, scope, args) { var listeners = this.taskQueue, i, ln, listener; for (i = 0 , ln = listeners.length; i < ln; i++) { listener = listeners[i]; if (fn === listener[0] && scope === listener[1] && args === listener[2]) { listeners.splice(i, 1); i--; ln--; } } }, invoke: function(listener) { var fn = listener[0], scope = listener[1], args = listener[2]; fn = (typeof fn == 'string' ? scope[fn] : fn); if (Ext.isArray(args)) { fn.apply(scope, args); } else { fn.call(scope, args); } }, whenIdle: function() { this.isIdle = true; this.processIdleQueue(); }, processIdleQueue: function() { if (!this.hasOwnProperty('idleQueueTimer')) { this.idleQueueTimer = Ext.defer(this.processIdleQueueItem, 1, this); } }, processIdleQueueItem: function() { delete this.idleQueueTimer; if (!this.isIdle) { return; } var listeners = this.idleQueue, listener; if (listeners.length > 0) { listener = listeners.shift(); this.invoke(listener); this.processIdleQueue(); } }, processTaskQueue: function() { if (!this.hasOwnProperty('taskQueueTimer')) { this.taskQueueTimer = Ext.defer(this.processTaskQueueItem, 15, this); } }, processTaskQueueItem: function() { delete this.taskQueueTimer; var listeners = this.taskQueue, listener; if (listeners.length > 0) { listener = listeners.shift(); this.invoke(listener); this.processTaskQueue(); } }, showFps: function() { Ext.onInternalReady(function() { Ext.Viewport.add([ { xtype: 'component', bottom: 50, left: 0, width: 50, height: 20, html: 'Average', style: 'background-color: black; color: white; text-align: center; line-height: 20px; font-size: 8px;' }, { id: '__averageFps', xtype: 'component', bottom: 0, left: 0, width: 50, height: 50, html: '0', style: 'background-color: red; color: white; text-align: center; line-height: 50px;' }, { xtype: 'component', bottom: 50, left: 50, width: 50, height: 20, html: 'Min (Last 1k)', style: 'background-color: black; color: white; text-align: center; line-height: 20px; font-size: 8px;' }, { id: '__minFps', xtype: 'component', bottom: 0, left: 50, width: 50, height: 50, html: '0', style: 'background-color: orange; color: white; text-align: center; line-height: 50px;' }, { xtype: 'component', bottom: 50, left: 100, width: 50, height: 20, html: 'Max (Last 1k)', style: 'background-color: black; color: white; text-align: center; line-height: 20px; font-size: 8px;' }, { id: '__maxFps', xtype: 'component', bottom: 0, left: 100, width: 50, height: 50, html: '0', style: 'background-color: yellow; color: black; text-align: center; line-height: 50px;' }, { xtype: 'component', bottom: 50, left: 150, width: 50, height: 20, html: 'Current', style: 'background-color: black; color: white; text-align: center; line-height: 20px; font-size: 8px;' }, { id: '__currentFps', xtype: 'component', bottom: 0, left: 150, width: 50, height: 50, html: '0', style: 'background-color: green; color: white; text-align: center; line-height: 50px;' } ]); Ext.AnimationQueue.resetFps(); }); }, resetFps: function() { var currentFps = Ext.getCmp('__currentFps'), averageFps = Ext.getCmp('__averageFps'), minFps = Ext.getCmp('__minFps'), maxFps = Ext.getCmp('__maxFps'), min = 1000, max = 0, count = 0, sum = 0; Ext.AnimationQueue.onFpsChanged = function(fps) { count++; if (!(count % 10)) { min = 1000; max = 0; } sum += fps; min = Math.min(min, fps); max = Math.max(max, fps); currentFps.setHtml(Math.round(fps)); averageFps.setHtml(Math.round(sum / count)); minFps.setHtml(Math.round(min)); maxFps.setHtml(Math.round(max)); }; } }, function() { var paramsString = window.location.search.substr(1), paramsArray = paramsString.split("&"); if (Ext.Array.contains(paramsArray, "showfps")) { Ext.AnimationQueue.showFps(); } }); Ext.define('Ext.ComponentManager', { alternateClassName: 'Ext.ComponentMgr', singleton: true, count: 0, typeName: 'xtype', constructor: function(config) { var me = this; Ext.apply(me, config || {}); me.all = {}; me.references = {}; me.onAvailableCallbacks = {}; }, create: function(config, defaultType) { if (typeof config === 'string') { return Ext.widget(config); } if (config.isComponent) { return config; } if ('xclass' in config) { return Ext.create(config.xclass, config); } return Ext.widget(config.xtype || defaultType, config); }, get: function(id) { return this.all[id]; }, register: function(component) { var me = this, all = me.all, key = component.getId(), onAvailableCallbacks = me.onAvailableCallbacks; if (key === undefined) { Ext.Error.raise('Component id is undefined. Please ensure the component has an id.'); } if (key in all) { Ext.Error.raise('Registering duplicate component id "' + key + '"'); } all[key] = component; if (component.reference) { me.references[key] = component; } ++me.count; if (!me.hasFocusListener) { Ext.on('focus', me.onGlobalFocus, me); me.hasFocusListener = true; } onAvailableCallbacks = onAvailableCallbacks && onAvailableCallbacks[key]; if (onAvailableCallbacks && onAvailableCallbacks.length) { me.notifyAvailable(component); } }, unregister: function(component) { var id = component.getId(); if (component.reference) { delete this.references[id]; } delete this.all[id]; this.count--; }, markReferencesDirty: function() { this.referencesDirty = true; }, fixReferences: function() { var me = this, references = me.references, key; if (me.referencesDirty) { for (key in references) { if (references.hasOwnProperty(key)) { references[key].fixReference(); } } me.referencesDirty = false; } }, onAvailable: function(id, fn, scope) { var me = this, callbacks = me.onAvailableCallbacks, all = me.all, item; if (id in all) { item = all[id]; fn.call(scope || item, item); } else if (id) { if (!Ext.isArray(callbacks[id])) { callbacks[id] = []; } callbacks[id].push(function(item) { fn.call(scope || item, item); }); } }, notifyAvailable: function(item) { var callbacks = this.onAvailableCallbacks[item && item.getId()] || []; while (callbacks.length) { (callbacks.shift())(item); } }, each: function(fn, scope) { return Ext.Object.each(this.all, fn, scope); }, getCount: function() { return this.count; }, getAll: function() { return Ext.Object.getValues(this.all); }, getActiveComponent: function() { return Ext.Component.fromElement(Ext.dom.Element.getActiveElement()); }, onGlobalFocus: function(e) { var me = this, toElement = e.toElement, fromElement = e.fromElement, toComponent = Ext.Component.fromElement(toElement), fromComponent = Ext.Component.fromElement(fromElement), commonAncestor = me.getCommonAncestor(fromComponent, toComponent), event, targetComponent; if (fromComponent && !(fromComponent.isDestroyed || fromComponent.destroying)) { if (fromComponent.focusable && fromElement === fromComponent.getFocusEl().dom) { event = new Ext.event.Event(e.event); event.type = 'blur'; event.target = fromElement; event.relatedTarget = toElement; fromComponent.onBlur(event); } for (targetComponent = fromComponent; targetComponent && targetComponent !== commonAncestor; targetComponent = targetComponent.getRefOwner()) { if (!(targetComponent.isDestroyed || targetComponent.destroying)) { targetComponent.onFocusLeave({ event: e.event, type: 'focusleave', target: fromElement, relatedTarget: toElement, fromComponent: fromComponent, toComponent: toComponent }); } } } if (toComponent && !toComponent.isDestroyed) { if (toComponent.focusable && toElement === toComponent.getFocusEl().dom) { event = new Ext.event.Event(e.event); event.type = 'focus'; event.relatedTarget = fromElement; event.target = toElement; toComponent.onFocus(event); } for (targetComponent = toComponent; targetComponent && targetComponent !== commonAncestor; targetComponent = targetComponent.getRefOwner()) { targetComponent.onFocusEnter({ event: e.event, type: 'focusenter', relatedTarget: fromElement, target: toElement, fromComponent: fromComponent, toComponent: toComponent }); } } }, getCommonAncestor: function(compA, compB) { if (compA === compB) { return compA; } while (compA && !(compA.isAncestor(compB) || compA === compB)) { compA = compA.getRefOwner(); } return compA; }, deprecated: { 5: { methods: { isRegistered: null, registerType: null } } } }, function() { Ext.getCmp = function(id) { return Ext.ComponentManager.get(id); }; }); Ext.ns('Ext.util').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; } }; Ext.define('Ext.util.LruCache', { extend: 'Ext.util.HashMap', config: { maxSize: null }, add: function(key, newValue) { var me = this, entry, last; me.removeAtKey(key); last = me.last; entry = { prev: last, next: null, key: key, value: newValue }; if (last) { last.next = entry; } else { me.first = entry; } me.last = entry; me.callParent([ key, entry ]); me.prune(); return newValue; }, insertBefore: function(key, newValue, sibling) { var me = this, existingKey, entry; if (sibling = this.map[this.findKey(sibling)]) { existingKey = me.findKey(newValue); if (existingKey) { me.unlinkEntry(entry = me.map[existingKey]); } else { entry = { prev: sibling.prev, next: sibling, key: key, value: newValue }; } if (sibling.prev) { entry.prev.next = entry; } else { me.first = entry; } entry.next = sibling; sibling.prev = entry; me.prune(); return newValue; } else { return me.add(key, newValue); } }, get: function(key) { var entry = this.map[key]; if (entry) { if (entry.next) { this.moveToEnd(entry); } return entry.value; } }, removeAtKey: function(key) { this.unlinkEntry(this.map[key]); return this.callParent(arguments); }, clear: function( initial) { this.first = this.last = null; return this.callParent(arguments); }, unlinkEntry: function(entry) { if (entry) { if (entry.next) { entry.next.prev = entry.prev; } else { this.last = entry.prev; } if (entry.prev) { entry.prev.next = entry.next; } else { this.first = entry.next; } entry.prev = entry.next = null; } }, moveToEnd: function(entry) { this.unlinkEntry(entry); if (entry.prev = this.last) { this.last.next = entry; } else { this.first = entry; } this.last = entry; }, getArray: function(isKey) { var arr = [], entry = this.first; while (entry) { arr.push(isKey ? entry.key : entry.value); entry = entry.next; } return arr; }, each: function(fn, scope, reverse) { var me = this, entry = reverse ? me.last : me.first, length = me.length; scope = scope || me; while (entry) { if (fn.call(scope, entry.key, entry.value, length) === false) { break; } entry = reverse ? entry.prev : entry.next; } return me; }, findKey: function(value) { var key, map = this.map; for (key in map) { if (map.hasOwnProperty(key) && map[key].value === value) { return key; } } return undefined; }, clone: function() { var newCache = new this.self(this.initialConfig), map = this.map, key; newCache.suspendEvents(); for (key in map) { if (map.hasOwnProperty(key)) { newCache.add(key, map[key].value); } } newCache.resumeEvents(); return newCache; }, prune: function() { var me = this, max = me.getMaxSize(), purgeCount = max ? (me.length - max) : 0; if (purgeCount > 0) { for (; me.first && purgeCount; purgeCount--) { me.removeAtKey(me.first.key); } } } }); Ext.define('Ext.ComponentQuery', { singleton: true, requires: [ 'Ext.ComponentManager', 'Ext.util.Operators', 'Ext.util.LruCache' ] }, function() { var cq = this, queryOperators = Ext.util.Operators, nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/, stripLeadingSpaceRe = /^(\s)+/, unescapeRe = /\\(.)/g, regexCache = new Ext.util.LruCache({ maxSize: 100 }), 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) { 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.getRefOwner())) { result.push(candidate); } } return result; }, 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; } }, filterByAttribute = function(items, property, operator, compareTo) { var result = [], i = 0, length = items.length, mustBeOwnProperty, presenceOnly, candidate, propValue, j, propLen, config; if (property.charAt(0) === '@') { mustBeOwnProperty = true; property = property.substr(1); } if (property.charAt(0) === '?') { mustBeOwnProperty = true; presenceOnly = true; property = property.substr(1); } for (; i < length; i++) { candidate = items[i]; config = candidate.self.$config.configs[property]; if (config) { propValue = candidate[config.names.get](); } else if (mustBeOwnProperty && !candidate.hasOwnProperty(property)) { continue; } else { propValue = candidate[property]; } if (presenceOnly) { result.push(candidate); } else if (operator === '~=') { if (propValue) { if (!Ext.isArray(propValue)) { propValue = propValue.split(' '); } for (j = 0 , propLen = propValue.length; j < propLen; j++) { if (queryOperators[operator](Ext.coerce(propValue[j], compareTo), compareTo)) { result.push(candidate); break; } } } } else if (operator === '/=') { if (propValue != null && compareTo.test(propValue)) { result.push(candidate); } } else if (!compareTo ? !!candidate[property] : queryOperators[operator](Ext.coerce(propValue, compareTo), compareTo)) { result.push(candidate); } } return result; }, 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; }, filterByPseudo = function(items, name, value) { return cq.pseudos[name](items, value); }, modeRe = /^(\s?([>\^])\s?|\s|$)/, tokenRe = /^(#)?((?:\\\.|[\w\-])+|\*)(?:\((true|false)\))?/, matchers = [ { re: /^\.((?:\\\.|[\w\-])+)(?:\((true|false)\))?/, method: filterByXType, argTransform: function(args) { var selector = args[0]; Ext.log.warn('"' + selector + '" ComponentQuery selector style is deprecated,' + ' use "' + selector.replace(/^\./, '') + '" without the leading dot instead'); if (args[1] !== undefined) { args[1] = args[1].replace(unescapeRe, '$1'); } return args.slice(1); } }, { re: /^(?:\[((?:[@?$])?[\w\-]*)\s*(?:([\^$*~%!\/]?=)\s*(['"])?((?:\\\]|.)*?)\3)?(?!\\)\])/, method: filterByAttribute, argTransform: function(args) { var selector = args[0], property = args[1], operator = args[2], compareTo = args[4], compareRe; if (compareTo !== undefined) { compareTo = compareTo.replace(unescapeRe, '$1'); var format = Ext.String.format, msg = "ComponentQuery selector '{0}' has an unescaped ({1}) character at the {2} " + "of the attribute value pattern. Usually that indicates an error " + "where the opening quote is not followed by the closing quote. " + "If you need to match a ({1}) character at the {2} of the attribute " + "value, escape the quote character in your pattern: (\\{1})", match; if (match = /^(['"]).*?[^'"]$/.exec(compareTo)) { Ext.log.warn(format(msg, selector, match[1], 'beginning')); } else if (match = /^[^'"].*?(['"])$/.exec(compareTo)) { Ext.log.warn(format(msg, selector, match[1], 'end')); } } if (operator === '/=') { compareRe = regexCache.get(compareTo); if (compareRe) { compareTo = compareRe; } else { compareTo = regexCache.add(compareTo, new RegExp(compareTo)); } } return [ property, operator, compareTo ]; } }, { re: /^#((?:\\\.|[\w\-])+)/, method: filterById }, { re: /^\:([\w\-]+)(?:\(((?:\{[^\}]+\})|(?:(?!\{)[^\s>\/]*?(?!\})))\))?/, method: filterByPseudo, argTransform: function(args) { if (args[2] !== undefined) { args[2] = args[2].replace(unescapeRe, '$1'); } return args.slice(1); } }, { re: /^(?:\{([^\}]+)\})/, method: filterFnPattern } ]; cq.Query = Ext.extend(Object, { constructor: function(cfg) { cfg = cfg || {}; Ext.apply(this, cfg); }, execute: function(root) { var operations = this.operations, result = [], op, i, len; for (i = 0 , len = operations.length; i < len; i++) { op = operations[i]; result = result.concat(this._execute(root, op)); } return result; }, _execute: function(root, operations) { var i = 0, length = operations.length, operation, workingItems; if (!root) { workingItems = Ext.ComponentManager.getAll(); } else if (Ext.isIterable(root)) { workingItems = root; } else if (root.isMixedCollection) { workingItems = root.items; } for (; i < length; i++) { operation = operations[i]; 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 (i === length - 1) { return workingItems; } } return []; }, is: function(component) { var operations = this.operations, result = false, len = operations.length, op, i; if (len === 0) { return true; } for (i = 0; i < len; i++) { op = operations[i]; result = this._is(component, op); if (result) { return result; } } return false; }, _is: function(component, operations) { var len = operations.length, active = [ component ], operation, i, j, mode, items, item; for (i = len - 1; i >= 0; --i) { operation = operations[i]; mode = operation.mode; if (mode) { if (mode === '^') { active = getItems(active, ' '); } else if (mode === '>') { items = []; for (j = 0 , len = active.length; j < len; ++j) { item = active[j].getRefOwner(); if (item) { items.push(item); } } active = items; } else { active = getAncestors(active); } if (active.length === 0) { return false; } } else { active = filterItems(active, operation); if (active.length === 0) { return false; } } } return true; }, getMatches: function(components, operations) { var len = operations.length, i; for (i = 0; i < len; ++i) { components = filterItems(components, operations[i]); if (components.length === 0) { break; } } return components; }, isMultiMatch: function() { return this.operations.length > 1; } }); Ext.apply(cq, { cache: new Ext.util.LruCache({ maxSize: 100 }), pseudos: { not: function(components, selector) { var 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; }, first: function(components) { var ret = []; if (components.length > 0) { ret.push(components[0]); } return ret; }, last: function(components) { var len = components.length, ret = []; if (len > 0) { ret.push(components[len - 1]); } return ret; }, focusable: function(cmps) { var len = cmps.length, results = [], i = 0, c; for (; i < len; i++) { c = cmps[i]; if (c.isFocusable && c.isFocusable()) { results.push(c); } } return results; }, "nth-child": function(c, a) { var result = [], m = nthRe.exec(a === "even" && "2n" || a === "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a), f = (m[1] || 1) - 0, len = m[2] - 0, i, n, nodeIndex; for (i = 0; n = c[i]; i++) { nodeIndex = i + 1; if (f === 1) { if (len === 0 || nodeIndex === len) { result.push(n); } } else if ((nodeIndex + len) % f === 0) { result.push(n); } } return result; } }, query: function(selector, root) { if (!selector) { return Ext.ComponentManager.all.getArray(); } var results = [], noDupResults = [], dupMatcher = {}, query = cq.cache.get(selector), resultsLn, cmp, i; if (!query) { query = cq.cache.add(selector, cq.parse(selector)); } results = query.execute(root); if (query.isMultiMatch()) { 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; }, visitPreOrder: function(selector, root, fn, scope, extraArgs) { cq._visit(true, selector, root, fn, scope, extraArgs); }, visitPostOrder: function(selector, root, fn, scope, extraArgs) { cq._visit(false, selector, root, fn, scope, extraArgs); }, _visit: function(preOrder, selector, root, fn, scope, extraArgs) { var query = cq.cache.get(selector), callArgs = [ root ], children, len = 0, i, rootMatch; if (!query) { query = cq.cache.add(selector, cq.parse(selector)); } rootMatch = query.is(root); if (root.getRefItems) { children = root.getRefItems(); len = children.length; } if (extraArgs) { Ext.Array.push(callArgs, extraArgs); } if (preOrder) { if (rootMatch) { if (fn.apply(scope || root, callArgs) === false) { return false; } } } for (i = 0; i < len; i++) { if (cq._visit.call(cq, preOrder, selector, children[i], fn, scope, extraArgs) === false) { return false; } } if (!preOrder) { if (rootMatch) { if (fn.apply(scope || root, callArgs) === false) { return false; } } } }, is: function(component, selector) { if (!selector) { return true; } var query = cq.cache.get(selector); if (!query) { query = cq.cache.add(selector, cq.parse(selector)); } return query.is(component); }, parse: function(selector) { var operations = [], selectors, sel, i, len; selectors = Ext.splitAndUnescape(selector, ','); for (i = 0 , len = selectors.length; i < len; i++) { sel = Ext.String.trim(selectors[i]); if (sel === '') { Ext.Error.raise('Invalid ComponentQuery selector: ""'); } operations.push(cq._parse(sel)); } return new cq.Query({ operations: operations }); }, _parse: function(selector) { var operations = [], trim = Ext.String.trim, length = matchers.length, lastSelector, tokenMatch, token, matchedChar, modeMatch, selectorMatch, transform, i, matcher, method, args; while (selector && lastSelector !== selector) { lastSelector = selector; tokenMatch = selector.match(tokenRe); if (tokenMatch) { matchedChar = tokenMatch[1]; token = trim(tokenMatch[2]).replace(unescapeRe, '$1'); if (matchedChar === '#') { operations.push({ method: filterById, args: [ token ] }); } else { operations.push({ method: filterByXType, args: [ token, Boolean(tokenMatch[3]) ] }); } selector = selector.replace(tokenMatch[0], '').replace(stripLeadingSpaceRe, '$1'); } while (!(modeMatch = selector.match(modeRe))) { for (i = 0; selector && i < length; i++) { matcher = matchers[i]; selectorMatch = selector.match(matcher.re); method = matcher.method; transform = matcher.argTransform; if (selectorMatch) { if (transform) { args = transform(selectorMatch); } else { args = selectorMatch.slice(1); } operations.push({ method: Ext.isString(matcher.method) ? Ext.functionFactory('items', Ext.String.format.apply(Ext.String, [ method ].concat(selectorMatch.slice(1)))) : matcher.method, args: args }); selector = selector.replace(selectorMatch[0], '').replace(stripLeadingSpaceRe, '$1'); break; } if (i === (length - 1)) { Ext.Error.raise('Invalid ComponentQuery selector: "' + arguments[0] + '"'); } } } if (modeMatch[1]) { operations.push({ mode: modeMatch[2] || modeMatch[1] }); selector = selector.replace(modeMatch[0], '').replace(stripLeadingSpaceRe, ''); } } return operations; } }); }); Ext.define('Ext.Evented', { alternateClassName: 'Ext.EventedBase', mixins: [ 'Ext.mixin.Observable' ], statics: { generateSetter: function(cfg) { var names = cfg.names, name = cfg.name, prefixedName = names.internal, applyName = names.apply, changeEventName = names.changeEvent, doSetName = names.doSet; return function(value) { var me = this, internalName = me.$configPrefixed ? prefixedName : name, initialized = me.initialized, oldValue, applier = me[applyName]; if (applier) { value = applier.call(me, value, me[internalName]); if (value === undefined) { return me; } } oldValue = me[internalName]; if (value !== oldValue) { if (initialized) { me.fireAction(changeEventName, [ me, value, oldValue ], me.doSet, me, { nameMap: names }); } else { me[internalName] = value; if (me[doSetName]) { me[doSetName](value, oldValue); } } } return this; }; } }, initialized: false, constructor: function(config) { this.mixins.observable.constructor.call(this, config); this.initialized = true; }, doSet: function(me, value, oldValue, options) { var nameMap = options.nameMap; me[nameMap.internal] = value; if (me[nameMap.doSet]) { me[nameMap.doSet].call(this, value, oldValue); } }, onClassExtended: function(cls, data) { if (!data.hasOwnProperty('eventedConfig')) { return; } var config = data.config, eventedConfig = data.eventedConfig, cacheName = 'eventedSetter', name, cfg; if (config) { Ext.applyIf(config, eventedConfig); } else { cls.addConfig(eventedConfig); } for (name in eventedConfig) { if (eventedConfig.hasOwnProperty(name)) { cfg = Ext.Config.get(name); data[cfg.names.set] = cfg[cacheName] || (cfg[cacheName] = this.generateSetter(cfg)); } } } }); Ext.define('Ext.util.Positionable', { mixinId: 'positionable', _positionTopLeft: [ 'position', 'top', 'left' ], _alignRe: /^([a-z]+)-([a-z]+)(\?)?$/, afterSetPosition: Ext.emptyFn, getAnchorToXY: function() { Ext.Error.raise("getAnchorToXY is not implemented in " + this.$className); }, getBorderPadding: function() { Ext.Error.raise("getBorderPadding is not implemented in " + this.$className); }, getLocalX: function() { Ext.Error.raise("getLocalX is not implemented in " + this.$className); }, getLocalXY: function() { Ext.Error.raise("getLocalXY is not implemented in " + this.$className); }, getLocalY: function() { Ext.Error.raise("getLocalY is not implemented in " + this.$className); }, getX: function() { Ext.Error.raise("getX is not implemented in " + this.$className); }, getXY: function() { Ext.Error.raise("getXY is not implemented in " + this.$className); }, getY: function() { Ext.Error.raise("getY is not implemented in " + this.$className); }, setLocalX: function() { Ext.Error.raise("setLocalX is not implemented in " + this.$className); }, setLocalXY: function() { Ext.Error.raise("setLocalXY is not implemented in " + this.$className); }, setLocalY: function() { Ext.Error.raise("setLocalY is not implemented in " + this.$className); }, setX: function() { Ext.Error.raise("setX is not implemented in " + this.$className); }, setXY: function() { Ext.Error.raise("setXY is not implemented in " + this.$className); }, setY: function() { Ext.Error.raise("setY is not implemented in " + this.$className); }, adjustForConstraints: function(xy, parent) { var vector = this.getConstrainVector(parent, xy); if (vector) { xy[0] += vector[0]; xy[1] += vector[1]; } return xy; }, alignTo: function(element, position, offsets, animate) { var me = this, el = me.el; return me.setXY(me.getAlignToXY(element, position, offsets), el.anim && !!animate ? el.anim(animate) : false); }, calculateAnchorXY: function(anchor, extraX, extraY, mySize) { var me = this, el = me.el, doc = document, isViewport = (el.dom === doc.body || el.dom === doc), round = Math.round, xy, myWidth, myHeight; anchor = (anchor || "tl").toLowerCase(); mySize = mySize || {}; myWidth = mySize.width || (isViewport ? Ext.Element.getViewportWidth() : me.getWidth()); myHeight = mySize.height || (isViewport ? Ext.Element.getViewportHeight() : me.getHeight()); switch (anchor) { case 'tl': xy = [ 0, 0 ]; break; case 'bl': xy = [ 0, myHeight ]; break; case 'tr': xy = [ myWidth, 0 ]; break; case 'c': xy = [ round(myWidth * 0.5), round(myHeight * 0.5) ]; break; case 't': xy = [ round(myWidth * 0.5), 0 ]; break; case 'l': xy = [ 0, round(myHeight * 0.5) ]; break; case 'r': xy = [ myWidth, round(myHeight * 0.5) ]; break; case 'b': xy = [ round(myWidth * 0.5), myHeight ]; break; case 'tc': xy = [ round(myWidth * 0.5), 0 ]; break; case 'bc': xy = [ round(myWidth * 0.5), myHeight ]; break; case 'br': xy = [ myWidth, myHeight ]; } return [ xy[0] + extraX, xy[1] + extraY ]; }, convertPositionSpec: Ext.identityFn, getAlignToXY: function(alignToEl, posSpec, offset) { var me = this, constrainToEl, constrainTo, alignMatch, myPosition, alignToElPosition, myWidth, myHeight, alignToElRegion, swapY, swapX, constrain, align1, align2, p1y, p1x, p2y, p2x, x, y; alignToEl = Ext.get(alignToEl.el || alignToEl); if (!alignToEl || !alignToEl.dom) { Ext.Error.raise({ sourceClass: 'Ext.util.Positionable', sourceMethod: 'getAlignToXY', msg: 'Attempted to align an element that doesn\'t exist' }); } offset = offset || [ 0, 0 ]; posSpec = (!posSpec || posSpec === "?" ? "tl-bl?" : (!(/-/).test(posSpec) && posSpec !== "" ? "tl-" + posSpec : posSpec || "tl-bl")).toLowerCase(); posSpec = me.convertPositionSpec(posSpec); alignMatch = posSpec.match(me._alignRe); if (!alignMatch) { Ext.Error.raise({ sourceClass: 'Ext.util.Positionable', sourceMethod: 'getAlignToXY', el: alignToEl, position: posSpec, offset: offset, msg: 'Attemmpted to align an element with an invalid position: "' + posSpec + '"' }); } align1 = alignMatch[1]; align2 = alignMatch[2]; constrain = !!alignMatch[3]; myPosition = me.getAnchorXY(align1, true); alignToElPosition = me.getAnchorToXY(alignToEl, align2, false); x = alignToElPosition[0] - myPosition[0] + offset[0]; y = alignToElPosition[1] - myPosition[1] + offset[1]; if (constrain) { constrainToEl = me.constrainTo || me.container || me.el.parent(); constrainToEl = Ext.get(constrainToEl.el || constrainToEl); constrainTo = constrainToEl.getConstrainRegion(); constrainTo.right = constrainTo.left + constrainToEl.el.dom.clientWidth; myWidth = me.getWidth(); myHeight = me.getHeight(); alignToElRegion = alignToEl.getRegion(); p1y = align1.charAt(0); p1x = align1.charAt(align1.length - 1); p2y = align2.charAt(0); p2x = align2.charAt(align2.length - 1); swapY = (x < alignToElRegion.right && x + myWidth >= alignToElRegion.left) && ((p1y == "t" && p2y == "b") || (p1y == "b" && p2y == "t")); swapX = (y < alignToElRegion.bottom && y + myHeight >= alignToElRegion.top) && ((p1x == "r" && p2x == "l") || (p1x == "l" && p2x == "r")); if (x + myWidth > constrainTo.right) { if (swapX) { x = alignToElRegion.left - myWidth; swapX = false; } else { x = constrainTo.right - myWidth; } } if (x < constrainTo.left) { x = swapX ? alignToElRegion.right : constrainTo.left; } if (y + myHeight > constrainTo.bottom) { if (swapY) { y = alignToElRegion.top - myHeight; swapY = false; } else { y = constrainTo.bottom - myHeight; } } if (y < constrainTo.top) { y = swapY ? alignToElRegion.bottom : constrainTo.top; } } return [ x, y ]; }, getAnchorXY: function(anchor, local, mySize) { var me = this, myPos = me.getXY(), el = me.el, doc = document, isViewport = el.dom == doc.body || el.dom == doc, scroll = el.getScroll(), extraX = isViewport ? scroll.left : local ? 0 : myPos[0], extraY = isViewport ? scroll.top : local ? 0 : myPos[1]; return me.calculateAnchorXY(anchor, extraX, extraY, mySize); }, getBox: function(contentBox, local) { var me = this, xy = local ? me.getLocalXY() : me.getXY(), x = xy[0], y = xy[1], w = me.getWidth(), h = me.getHeight(), borderPadding, beforeX, beforeY; if (contentBox) { borderPadding = me.getBorderPadding(); beforeX = borderPadding.beforeX; beforeY = borderPadding.beforeY; x += beforeX; y += beforeY; w -= (beforeX + borderPadding.afterX); h -= (beforeY + borderPadding.afterY); } return { x: x, left: x, 0: x, y: y, top: y, 1: y, width: w, height: h, right: x + w, bottom: y + h }; }, calculateConstrainedPosition: function(constrainTo, proposedPosition, local, proposedSize) { var me = this, vector, fp = me.floatParent, parentNode = fp ? fp.getTargetEl() : null, parentOffset, borderPadding, proposedConstrainPosition, xy = false, localXY; if (local && fp) { parentOffset = parentNode.getXY(); borderPadding = parentNode.getBorderPadding(); parentOffset[0] += borderPadding.beforeX; parentOffset[1] += borderPadding.beforeY; if (proposedPosition) { proposedConstrainPosition = [ proposedPosition[0] + parentOffset[0], proposedPosition[1] + parentOffset[1] ]; } } else { proposedConstrainPosition = proposedPosition; } constrainTo = constrainTo || me.constrainTo || parentNode || me.container || me.el.parent(); if (local && proposedConstrainPosition) { proposedConstrainPosition = me.reverseTranslateXY(proposedConstrainPosition); } vector = ((me.constrainHeader && me.header.rendered) ? me.header : me).getConstrainVector(constrainTo, proposedConstrainPosition, proposedSize); if (vector) { xy = proposedPosition || me.getPosition(local); xy[0] += vector[0]; xy[1] += vector[1]; } return xy; }, getConstrainRegion: function() { var me = this, el = me.el, isBody = el.dom.nodeName === 'BODY', dom = el.dom, borders = el.getBorders(), pos = el.getXY(), left = pos[0] + borders.beforeX, top = pos[1] + borders.beforeY, scroll, width, height; if (isBody) { scroll = el.getScroll(); left = scroll.left; top = scroll.top; width = Ext.Element.getViewportWidth(); height = Ext.Element.getViewportHeight(); } else { width = dom.clientWidth; height = dom.clientHeight; } return new Ext.util.Region(top, left + width, top + height, left); }, getConstrainVector: function(constrainTo, proposedPosition, proposedSize) { var thisRegion = this.getRegion(), vector = [ 0, 0 ], shadowSize = (this.shadow && this.constrainShadow && !this.shadowDisabled) ? this.shadow.getShadowSize() : undefined, overflowed = false, constrainSize, constraintInsets = this.constraintInsets; if (!(constrainTo instanceof Ext.util.Region)) { constrainTo = Ext.get(constrainTo.el || constrainTo); constrainSize = constrainTo.getViewSize(); constrainTo = constrainTo.getConstrainRegion(); constrainTo.right = constrainTo.left + constrainSize.width; constrainTo.bottom = constrainTo.top + constrainSize.height; } if (constraintInsets) { constraintInsets = Ext.isObject(constraintInsets) ? constraintInsets : Ext.Element.parseBox(constraintInsets); constrainTo.adjust(constraintInsets.top, constraintInsets.right, constraintInsets.bottom, constraintInsets.length); } if (proposedPosition) { thisRegion.translateBy(proposedPosition[0] - thisRegion.x, proposedPosition[1] - thisRegion.y); } if (proposedSize) { thisRegion.right = thisRegion.left + proposedSize[0]; thisRegion.bottom = thisRegion.top + proposedSize[1]; } if (shadowSize) { constrainTo.adjust(shadowSize[0], -shadowSize[1], -shadowSize[2], shadowSize[3]); } 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; }, getOffsetsTo: function(offsetsTo) { var o = this.getXY(), e = Ext.fly(offsetsTo.el || offsetsTo).getXY(); return [ o[0] - e[0], o[1] - e[1] ]; }, getRegion: function() { var box = this.getBox(); return new Ext.util.Region(box.top, box.right, box.bottom, box.left); }, getViewRegion: function() { var me = this, el = me.el, isBody = el.dom.nodeName === 'BODY', borderPadding, scroll, pos, top, left, width, height; if (isBody) { scroll = el.getScroll(); left = scroll.left; top = scroll.top; width = Ext.Element.getViewportWidth(); height = Ext.Element.getViewportHeight(); } else { borderPadding = me.getBorderPadding(); pos = me.getXY(); left = pos[0] + borderPadding.beforeX; top = pos[1] + borderPadding.beforeY; width = me.getWidth(true); height = me.getHeight(true); } return new Ext.util.Region(top, left + width, top + height, left); }, 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.setXY([ hash[direction][0], hash[direction][1] ], animate); }, setBox: function(box) { var me = this, x, y; if (box.isRegion) { box = { x: box.left, y: box.top, width: box.right - box.left, height: box.bottom - box.top }; } me.constrainBox(box); x = box.x; y = box.y; me.setXY([ x, y ]); me.setSize(box.width, box.height); me.afterSetPosition(x, y); return me; }, constrainBox: function(box) { var me = this, constrainedPos, x, y; if (me.constrain || me.constrainHeader) { x = ('x' in box) ? box.x : box.left; y = ('y' in box) ? box.y : box.top; constrainedPos = me.calculateConstrainedPosition(null, [ x, y ], false, [ box.width, box.height ]); if (constrainedPos) { box.x = constrainedPos[0]; box.y = constrainedPos[1]; } } }, translatePoints: function(x, y) { var pos = this.translateXY(x, y); return { left: pos.x, top: pos.y }; }, translateXY: function(x, y) { var me = this, el = me.el, styles = el.getStyle(me._positionTopLeft), relative = styles.position === 'relative', left = parseFloat(styles.left), top = parseFloat(styles.top), xy = me.getXY(); if (Ext.isArray(x)) { y = x[1]; x = x[0]; } if (isNaN(left)) { left = relative ? 0 : el.dom.offsetLeft; } if (isNaN(top)) { top = relative ? 0 : el.dom.offsetTop; } left = (typeof x === 'number') ? x - xy[0] + left : undefined; top = (typeof y === 'number') ? y - xy[1] + top : undefined; return { x: left, y: top }; }, reverseTranslateXY: function(xy) { var coords = xy, el = this.el, translatedXY = [], dom = el.dom, offsetParent = dom.offsetParent, relative, offsetParentXY, x, y; if (offsetParent) { relative = el.isStyle('position', 'relative') , offsetParentXY = Ext.fly(offsetParent).getXY() , x = xy[0] + offsetParentXY[0] + offsetParent.clientLeft; y = xy[1] + offsetParentXY[1] + offsetParent.clientTop; if (relative) { x += el.getPadding('l'); y += el.getPadding('t'); } coords = [ x, y ]; } return coords; } }); Ext.define('Ext.overrides.util.Positionable', { override: 'Ext.util.Positionable', anchorTo: function(anchorToEl, alignment, offsets, animate, monitorScroll, callback) { var me = this, scroll = !Ext.isEmpty(monitorScroll), action = function() { me.alignTo(anchorToEl, alignment, offsets, animate); Ext.callback(callback, me); }, anchor = me.getAnchor(); me.removeAnchor(); Ext.apply(anchor, { fn: action, scroll: scroll }); Ext.on('resize', action, null); if (scroll) { Ext.getWin().on('scroll', action, null, { buffer: !isNaN(monitorScroll) ? monitorScroll : 50 }); } action(); return me; }, getAnchor: function() { var el = this.el, data, anchor; if (!el.dom) { return; } data = el.getData(); anchor = data._anchor; if (!anchor) { anchor = data._anchor = {}; } return anchor; }, removeAnchor: function() { var anchor = this.getAnchor(); if (anchor && anchor.fn) { Ext.un('resize', anchor.fn); if (anchor.scroll) { Ext.getWin().on('scroll', anchor.fn); } delete anchor.fn; } return this; }, setBox: function(box, animate) { var me = this; if (box.isRegion) { box = { x: box.left, y: box.top, width: box.right - box.left, height: box.bottom - box.top }; } if (animate) { me.constrainBox(box); me.animate(Ext.applyIf({ to: box, listeners: { afteranimate: Ext.Function.bind(me.afterSetPosition, me, [ box.x, box.y ]) } }, animate)); } else { me.callParent([ box ]); } return me; } }); Ext.define('Ext.dom.UnderlayPool', { constructor: function(elementConfig) { this.elementConfig = elementConfig; this.cache = []; }, checkOut: function() { var el = this.cache.shift(); if (!el) { el = Ext.Element.create(this.elementConfig); el.setVisibilityMode(2); el.dom.setAttribute('data-sticky', true); } return el; }, checkIn: function(el) { this.cache.push(el); }, reset: function() { var cache = this.cache, i = cache.length; while (i--) { cache[i].destroy(); } this.cache = []; } }); Ext.define('Ext.dom.Underlay', { requires: [ 'Ext.dom.UnderlayPool' ], constructor: function(config) { Ext.apply(this, config); }, beforeShow: Ext.emptyFn, getInsertionTarget: function() { return this.target; }, getPool: function() { return this.pool || (this.self.prototype.pool = new Ext.dom.UnderlayPool(this.elementConfig)); }, hide: function() { var me = this, el = me.el; if (el) { el.hide(); me.getPool().checkIn(el); me.el = null; me.hidden = true; } }, realign: function(x, y, width, height) { var me = this, el = me.el, target = me.target, offsets = me.offsets, max = Math.max; if (el) { if (x == null) { x = target.getX(); } if (y == null) { y = target.getY(); } if (width == null) { width = target.getWidth(); } if (height == null) { height = target.getHeight(); } if (offsets) { x = x + offsets.x; y = y + offsets.y; width = max(width + offsets.w, 0); height = max(height + offsets.h, 0); } el.setXY([ x, y ]); el.setSize(width, height); } }, setZIndex: function(zIndex) { this.zIndex = zIndex; if (this.el) { this.el.setStyle("z-index", zIndex); } }, show: function() { var me = this, target = me.target, zIndex = me.zIndex, el = me.el, insertionTarget = me.getInsertionTarget().dom, dom; if (!el) { el = me.el = me.getPool().checkOut(); } me.beforeShow(); if (zIndex == null) { zIndex = (parseInt(target.getStyle("z-index"), 10)); } if (zIndex) { el.setStyle("z-index", zIndex); } el.setStyle('position', me.fixed ? 'fixed' : ''); dom = el.dom; if (dom.nextSibling !== insertionTarget) { target.dom.parentNode.insertBefore(dom, insertionTarget); } el.show(); me.realign(); me.hidden = false; } }); Ext.define('Ext.dom.Shadow', { extend: 'Ext.dom.Underlay', alternateClassName: 'Ext.Shadow', mode: 'drop', offset: 4, cls: Ext.baseCSSPrefix + (!Ext.supports.CSS3BoxShadow ? 'ie' : 'css') + '-shadow', constructor: function(config) { var me = this, outerOffsets, offsets, offset, rad; me.callParent([ config ]); me.elementConfig = { cls: me.cls, role: 'presentation' }; offset = me.offset; rad = Math.floor(offset / 2); me.opacity = 50; switch (me.mode.toLowerCase()) { case "drop": outerOffsets = { x: 0, y: 0, w: offset, h: offset }; if (Ext.supports.CSS3BoxShadow) { offsets = { x: offset, y: offset, h: -offset, w: -offset }; } else { offsets = { x: -rad, y: -rad, h: -rad, w: -rad }; }; break; case "sides": outerOffsets = { x: -offset, y: 0, w: offset * 2, h: offset }; if (Ext.supports.CSS3BoxShadow) { offsets = { x: 0, y: offset, h: -offset, w: 0 }; } else { offsets = { x: 1 + rad - 2 * offset, y: -(1 + rad), h: -1, w: rad - 1 }; }; break; case "frame": outerOffsets = { x: -offset, y: -offset, w: offset * 2, h: offset * 2 }; if (Ext.supports.CSS3BoxShadow) { offsets = { x: 0, y: 0, h: 0, w: 0 }; } else { offsets = { x: 1 + rad - 2 * offset, y: 1 + rad - 2 * offset, h: offset - rad - 1, w: offset - rad - 1 }; }; break; case "bottom": outerOffsets = { x: -offset, y: 0, w: offset * 2, h: offset }; if (Ext.supports.CSS3BoxShadow) { offsets = { x: 0, y: offset, h: -offset, w: 0 }; } else { offsets = { x: 0, y: offset, h: 0, w: 0 }; }; break; } me.offsets = offsets; me.outerOffsets = outerOffsets; }, getShadowSize: function() { var me = this, offset = me.el ? me.offset : 0, result = [ offset, offset, offset, offset ], mode = me.mode.toLowerCase(); if (me.el && mode !== 'frame') { result[0] = 0; if (mode == 'drop') { result[3] = 0; } } return result; }, boxShadowProperty: (function() { var property = 'boxShadow', style = document.documentElement.style; if (!('boxShadow' in style)) { if ('WebkitBoxShadow' in style) { property = 'WebkitBoxShadow'; } else if ('MozBoxShadow' in style) { property = 'MozBoxShadow'; } } return property; }()), beforeShow: function() { var me = this, style = me.el.dom.style, shim = me.shim; if (Ext.supports.CSS3BoxShadow) { style[me.boxShadowProperty] = '0 0 ' + (me.offset + 2) + 'px #888'; } else { style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=" + me.opacity + ") progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (me.offset) + ")"; } if (shim) { shim.realign(); } }, setOpacity: function(opacity) { var el = this.el; if (el) { if (Ext.isIE && !Ext.supports.CSS3BoxShadow) { opacity = Math.floor(opacity * 100 / 2) / 100; } this.opacity = opacity; el.setOpacity(opacity); } } }); Ext.define('Ext.dom.Shim', { extend: 'Ext.dom.Underlay', cls: Ext.baseCSSPrefix + 'shim', constructor: function(config) { this.callParent([ config ]); this.elementConfig = { tag: 'iframe', cls: this.cls, role: 'presentation', frameBorder: '0', src: Ext.SSL_SECURE_URL, tabindex: '-1' }; }, getInsertionTarget: function() { var shadow = this.shadow; return (shadow && shadow.el) || this.target; } }); Ext.define('Ext.dom.ElementEvent', { extend: 'Ext.util.Event', addListener: function(fn, scope, options, caller, manager) { var me = this, added = false, name = me.name, captures, directs, directCaptures; options = options || {}; if (options.delegated === false || Ext.event.publisher.Dom.instance.directEvents[name]) { if (options.capture) { directCaptures = me.directCaptures || (me.directCaptures = new Ext.util.Event(me.observable, name)); added = directCaptures.addListener(fn, scope, options, caller, manager); } else { directs = me.directs || (me.directs = new Ext.util.Event(me.observable, name)); added = directs.addListener(fn, scope, options, caller, manager); } } else if (options.capture) { captures = me.captures || (me.captures = new Ext.util.Event(me.observable, name)); added = captures.addListener(fn, scope, options, caller, manager); } else { added = me.callParent([ fn, scope, options, caller, manager ]); } return added; }, removeListener: function(fn, scope) { var me = this, captures = me.captures, directs = me.directs, directCaptures = me.directCaptures, removed = false, index = me.findListener(fn, scope); if (index !== -1) { removed = me.callParent([ fn, scope, index ]); } else { if (directs) { index = directs.findListener(fn, scope); } if (index !== -1) { removed = directs.removeListener(fn, scope, index); } else { if (captures) { index = captures.findListener(fn, scope); } if (index !== -1) { removed = captures.removeListener(fn, scope, index); } else if (directCaptures) { index = directCaptures.findListener(fn, scope); if (index !== -1) { removed = directCaptures.removeListener(fn, scope, index); } } } } return removed; }, clearListeners: function() { var me = this, directCaptures = me.directCaptures, directs = me.directs, captures = me.captures; if (directCaptures) { directCaptures.clearListeners(); } if (directs) { directs.clearListeners(); } if (captures) { captures.clearListeners(); } me.callParent(); }, suspend: function() { var me = this, directCaptures = me.directCaptures, directs = me.directs, captures = me.captures; if (directCaptures) { directCaptures.suspend(); } if (directs) { directs.suspend(); } if (captures) { captures.suspend(); } me.callParent(); }, resume: function() { var me = this, directCaptures = me.directCaptures, directs = me.directs, captures = me.captures; if (directCaptures) { directCaptures.resume(); } if (directs) { directs.resume(); } if (captures) { captures.resume(); } me.callParent(); } }); Ext.define('Ext.event.publisher.Publisher', { handledEvents: [], statics: { publishers: {}, publishersByEvent: {} }, constructor: function() { var me = this, type = me.type; me.handles = {}; if (!type) { Ext.Error.raise("Event publisher '" + me.$className + "' defined without a 'type' property."); } if (me.self.instance) { Ext.Error.raise("Cannot create multiple instances of '" + me.$className + "'. " + "Use '" + me.$className + ".instance' to retrieve the singleton instance."); } me.registerEvents(); Ext.event.publisher.Publisher.publishers[type] = me; }, registerEvents: function(events) { var me = this, publishersByEvent = Ext.event.publisher.Publisher.publishersByEvent, handledEvents = events || me.handledEvents, ln = handledEvents.length, eventName, i; for (i = 0; i < ln; i++) { eventName = handledEvents[i]; me.handles[eventName] = 1; publishersByEvent[eventName] = me; } }, fire: function(element, eventName, args) { var event; if (element.hasListeners[eventName]) { event = element.events[eventName]; if (event) { event.fire.apply(event, args); } } }, subscribe: function() { Ext.Error.raise("Ext.event.publisher.Publisher subclass '" + this.$className + '" has no subscribe method.'); }, unsubscribe: function() { Ext.Error.raise("Ext.event.publisher.Publisher subclass '" + this.$className + '" has no unsubscribe method.'); }, destroy: Ext.emptyFn }); 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.Region', { requires: [ 'Ext.util.Offset' ], isRegion: true, statics: { getRegion: function(el) { return Ext.fly(el).getRegion(); }, 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 = new 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.util.Point', { extend: 'Ext.util.Region', radianToDegreeConstant: 180 / Math.PI, origin: { x: 0, y: 0 }, statics: { fromEvent: function(e) { var changedTouches = e.changedTouches, touch = (changedTouches && changedTouches.length > 0) ? changedTouches[0] : e; return this.fromTouch(touch); }, fromTouch: function(touch) { return new this(touch.pageX, touch.pageY); }, from: function(object) { if (!object) { return new this(0, 0); } if (!(object instanceof this)) { return new this(object.x, object.y); } return object; } }, constructor: function(x, y) { if (x == null) { x = 0; } if (y == null) { y = 0; } this.callParent([ y, x, y, x ]); }, clone: function() { return new this.self(this.x, this.y); }, copy: function() { return this.clone.apply(this, arguments); }, copyFrom: function(point) { this.x = point.x; this.y = point.y; return this; }, toString: function() { return "Point[" + this.x + "," + this.y + "]"; }, isCloseTo: function(point, threshold) { if (typeof threshold == 'number') { return this.getDistanceTo(point) <= threshold; } var x = point.x, y = point.y, thresholdX = threshold.x, thresholdY = threshold.y; return (this.x <= x + thresholdX && this.x >= x - thresholdX && this.y <= y + thresholdY && this.y >= y - thresholdY); }, isWithin: function() { return this.isCloseTo.apply(this, arguments); }, isContainedBy: function(region) { if (!(region instanceof Ext.util.Region)) { region = Ext.get(region.el || region).getRegion(); } return region.contains(this); }, roundedEquals: function(point) { if (!point || typeof point !== 'object') { point = this.origin; } return (Math.round(this.x) === Math.round(point.x) && Math.round(this.y) === Math.round(point.y)); }, getDistanceTo: function(point) { if (!point || typeof point !== 'object') { point = this.origin; } var deltaX = this.x - point.x, deltaY = this.y - point.y; return Math.sqrt(deltaX * deltaX + deltaY * deltaY); }, getAngleTo: function(point) { if (!point || typeof point !== 'object') { point = this.origin; } var deltaX = this.x - point.x, deltaY = this.y - point.y; return Math.atan2(deltaY, deltaX) * this.radianToDegreeConstant; } }, function() { this.prototype.translate = this.prototype.translateBy; }); Ext.define('Ext.event.Event', { alternateClassName: 'Ext.EventObjectImpl', requires: [ 'Ext.util.Point' ], isStopped: false, defaultPrevented: false, isEvent: true, statics: { resolveTextNode: function(node) { return (node && node.nodeType === 3) ? node.parentNode : node; }, pointerEvents: { pointerdown: 1, pointermove: 1, pointerup: 1, pointercancel: 1, pointerover: 1, pointerout: 1, pointerenter: 1, pointerleave: 1, MSPointerDown: 1, MSPointerMove: 1, MSPointerUp: 1, MSPointerOver: 1, MSPointerOut: 1, MSPointerCancel: 1, MSPointerEnter: 1, MSPointerLeave: 1 }, mouseEvents: { mousedown: 1, mousemove: 1, mouseup: 1, mouseover: 1, mouseout: 1, mouseenter: 1, mouseleave: 1 }, clickEvents: { click: 1, dblclick: 1 }, touchEvents: { touchstart: 1, touchmove: 1, touchend: 1, touchcancel: 1 }, focusEvents: { focus: 1, blur: 1, focusin: 1, focusout: 1, focusenter: 1, focusleave: 1 }, pointerTypes: { 2: 'touch', 3: 'pen', 4: 'mouse', touch: 'touch', pen: 'pen', mouse: 'mouse' } }, constructor: function(event) { var me = this, self = me.self, resolveTextNode = me.self.resolveTextNode, changedTouches = event.changedTouches, coordinateOwner = changedTouches ? changedTouches[0] : event, type = event.type, pointerType, relatedTarget; me.pageX = coordinateOwner.pageX; me.pageY = coordinateOwner.pageY; me.target = me.delegatedTarget = resolveTextNode(event.target); relatedTarget = event.relatedTarget; if (relatedTarget) { me.relatedTarget = resolveTextNode(relatedTarget); } me.browserEvent = me.event = event; me.type = type; me.button = event.button || 0; me.shiftKey = event.shiftKey; me.ctrlKey = event.ctrlKey || event.metaKey || false; me.altKey = event.altKey; me.charCode = event.charCode; me.keyCode = event.keyCode; me.buttons = event.buttons; if (me.button === 0 && me.buttons === 0) { me.buttons = 1; } if (self.forwardTab !== undefined && self.focusEvents[type]) { me.forwardTab = self.forwardTab; } if (self.mouseEvents[type] || self.clickEvents[type]) { pointerType = 'mouse'; } else if (self.pointerEvents[type]) { pointerType = self.pointerTypes[event.pointerType]; } else if (self.touchEvents[type]) { pointerType = 'touch'; } if (pointerType) { me.pointerType = pointerType; } me.timeStamp = me.time = +(event.timeStamp || new Date()); }, chain: function(props) { var e = Ext.Object.chain(this); e.parentEvent = this; return Ext.apply(e, props); }, correctWheelDelta: function(delta) { var scale = this.WHEEL_SCALE, ret = Math.round(delta / scale); if (!ret && delta) { ret = (delta < 0) ? -1 : 1; } return ret; }, getCharCode: function() { return this.charCode || this.keyCode; }, getKey: function() { return this.keyCode || this.charCode; }, getPoint: function() { var xy = this.getXY(); return new Ext.util.Point(xy[0], xy[1]); }, getRelatedTarget: function(selector, maxDepth, returnEl) { var relatedTarget = this.relatedTarget, target = null; if (relatedTarget) { if (selector) { target = Ext.fly(relatedTarget).findParent(selector, maxDepth, returnEl); } else { target = returnEl ? Ext.get(relatedTarget) : relatedTarget; } } return target; }, getTarget: function(selector, maxDepth, returnEl) { return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target); }, getTime: function() { return this.time; }, getWheelDelta: function() { var deltas = this.getWheelDeltas(); return deltas.y; }, getWheelDeltas: function() { var me = this, event = me.browserEvent, dx = 0, dy = 0; if (Ext.isDefined(event.wheelDeltaX)) { dx = event.wheelDeltaX; dy = event.wheelDeltaY; } else if (event.wheelDelta) { dy = event.wheelDelta; } else if (event.detail) { dy = -event.detail; if (dy > 100) { dy = 3; } else if (dy < -100) { dy = -3; } if (Ext.isDefined(event.axis) && event.axis === event.HORIZONTAL_AXIS) { dx = dy; dy = 0; } } return { x: me.correctWheelDelta(dx), y: me.correctWheelDelta(dy) }; }, getX: function() { return this.getXY()[0]; }, getXY: function() { var me = this, xy = me.xy; if (!xy) { xy = me.xy = [ me.pageX, me.pageY ]; var x = xy[0], browserEvent, doc, docEl, body; if (!x && x !== 0) { browserEvent = me.browserEvent; doc = document; docEl = doc.documentElement; body = doc.body; xy[0] = browserEvent.clientX + (docEl && docEl.scrollLeft || body && body.scrollLeft || 0) - (docEl && docEl.clientLeft || body && body.clientLeft || 0); xy[1] = browserEvent.clientY + (docEl && docEl.scrollTop || body && body.scrollTop || 0) - (docEl && docEl.clientTop || body && body.clientTop || 0); } } return xy; }, getY: function() { return this.getXY()[1]; }, hasModifier: function() { var me = this; return !!(me.ctrlKey || me.altKey || me.shiftKey || me.metaKey); }, isNavKeyPress: function(scrollableOnly) { var me = this, k = me.keyCode; return (k >= 33 && k <= 40) || (!scrollableOnly && (k === me.RETURN || k === me.TAB || k === me.ESC)); }, isSpecialKey: function() { var k = this.keyCode; return (this.type === 'keypress' && this.ctrlKey) || this.isNavKeyPress() || (k === this.BACKSPACE) || (k >= 16 && k <= 20) || (k >= 44 && k <= 46); }, makeUnpreventable: function() { this.browserEvent.preventDefault = Ext.emptyFn; }, preventDefault: function() { var me = this, parentEvent = me.parentEvent; me.defaultPrevented = true; if (parentEvent) { parentEvent.defaultPrevented = true; } me.browserEvent.preventDefault(); return me; }, setCurrentTarget: function(target) { this.currentTarget = this.delegatedTarget = target; }, stopEvent: function() { return this.preventDefault().stopPropagation(); }, stopPropagation: function() { var me = this, browserEvent = me.browserEvent, parentEvent = me.parentEvent; me.isStopped = true; if (parentEvent) { parentEvent.isStopped = true; } if (!browserEvent.stopPropagation) { browserEvent.cancelBubble = true; return me; } browserEvent.stopPropagation(); return me; }, within: function(el, related, allowEl) { var t; if (el) { t = related ? this.getRelatedTarget() : this.getTarget(); } return t ? Ext.fly(el).contains(t) || !!(allowEl && t === Ext.getDom(el)) : false; }, deprecated: { '4.0': { methods: { getPageX: 'getX', getPageY: 'getY' } } } }, function(Event) { var prototype = Event.prototype, constants = { 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, WHEEL_SCALE: (function() { var scale; if (Ext.isGecko) { scale = 3; } else if (Ext.isMac) { if (Ext.isSafari && Ext.webKitVersion >= 532) { scale = 120; } else { scale = 12; } scale *= 3; } else { scale = 120; } return scale; }()) }; Ext.apply(Event, constants); Ext.apply(prototype, constants); prototype.getTrueXY = prototype.getXY; }); Ext.define('Ext.overrides.event.Event', { override: 'Ext.event.Event', mousedownEvents: { mousedown: 1, pointerdown: 1, touchstart: 1 }, injectEvent: (function() { var API, dispatchers = {}, crazyIEButtons; if (!Ext.isIE9m && 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); } }; } else if (document.createEventObject) { 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); } }; } 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 = {}; } function cannotInject(target, srcEvent) {} return function(target) { var me = this, dispatcher = dispatchers[me.type] || cannotInject, t = target ? (target.dom || target) : me.getTarget(); dispatcher(t, me); }; }()), preventDefault: function() { var me = this, event = me.browserEvent, parentEvent = me.parentEvent, unselectable, target; if (typeof event.type !== 'unknown') { me.defaultPrevented = true; if (parentEvent) { parentEvent.defaultPrevented = true; } if (event.preventDefault) { event.preventDefault(); } else { if (event.type === 'mousedown') { target = event.target; unselectable = target.getAttribute('unselectable'); if (unselectable !== 'on') { target.setAttribute('unselectable', 'on'); Ext.defer(function() { target.setAttribute('unselectable', unselectable); }, 1); } } event.returnValue = false; if (event.ctrlKey || event.keyCode > 111 && event.keyCode < 124) { event.keyCode = -1; } } } return me; }, stopPropagation: function() { var me = this, event = me.browserEvent; if (typeof event.type !== 'unknown') { if (me.mousedownEvents[me.type]) { Ext.GlobalEvents.fireMouseDown(me); } me.callParent(); } return me; }, deprecated: { '5.0': { methods: { clone: function() { return new this.self(this.browserEvent, this); } } } } }, function() { var Event = this, btnMap, onKeyDown = function(e) { if (e.keyCode === 9) { Event.forwardTab = !e.shiftKey; } }, onKeyUp = function(e) { if (e.keyCode === 9) { delete Event.forwardTab; } }; if (Ext.isIE9m) { btnMap = { 0: 0, 1: 0, 4: 1, 2: 2 }; Event.override({ statics: { enableIEAsync: function(browserEvent) { var name, fakeEvent = {}; for (name in browserEvent) { fakeEvent[name] = browserEvent[name]; } return fakeEvent; } }, constructor: function(event, info, touchesMap, identifiers) { var me = this; me.callParent([ event, info, touchesMap, identifiers ]); me.button = btnMap[event.button]; if (event.type === 'contextmenu') { me.button = 2; } me.toElement = event.toElement; me.fromElement = event.fromElement; }, mouseLeaveRe: /(mouseout|mouseleave)/, mouseEnterRe: /(mouseover|mouseenter)/, enableIEAsync: function(browserEvent) { this.browserEvent = this.self.enableIEAsync(browserEvent); }, getRelatedTarget: function(selector, maxDepth, returnEl) { var me = this, type, target; if (!me.relatedTarget) { type = me.type; if (me.mouseLeaveRe.test(type)) { target = me.toElement; } else if (me.mouseEnterRe.test(type)) { target = me.fromElement; } if (target) { me.relatedTarget = me.self.resolveTextNode(target); } } return me.callParent([ selector, maxDepth, returnEl ]); } }); document.attachEvent('onkeydown', onKeyDown); document.attachEvent('onkeyup', onKeyUp); window.attachEvent('onunload', function() { document.detachEvent('onkeydown', onKeyDown); document.detachEvent('onkeyup', onKeyUp); }); } else if (document.addEventListener) { document.addEventListener('keydown', onKeyDown, true); document.addEventListener('keyup', onKeyUp, true); } }); Ext.define('Ext.event.publisher.Dom', { extend: 'Ext.event.publisher.Publisher', requires: [ 'Ext.event.Event' ], type: 'dom', handledDomEvents: [], reEnterCount: 0, captureEvents: { resize: 1, focus: 1, blur: 1, paste: 1, input: 1, change: 1, animationstart: 1, animationend: 1, scroll: 1 }, directEvents: { mouseenter: 1, mouseleave: 1, pointerenter: 1, pointerleave: 1, MSPointerEnter: 1, MSPointerLeave: 1, load: 1, unload: 1, beforeunload: 1, error: 1, DOMContentLoaded: 1, DOMFrameContentLoaded: 1, hashchange: 1 }, blockedPointerEvents: { pointerover: 1, pointerout: 1, pointerenter: 1, pointerleave: 1, MSPointerOver: 1, MSPointerOut: 1, MSPointerEnter: 1, MSPointerLeave: 1 }, blockedCompatibilityMouseEvents: { mouseenter: 1, mouseleave: 1 }, constructor: function() { var me = this; me.bubbleSubscribers = {}; me.captureSubscribers = {}; me.directSubscribers = {}; me.directCaptureSubscribers = {}; me.delegatedListeners = {}; me.initHandlers(); Ext.onInternalReady(me.onReady, me); me.callParent(); }, registerEvents: function() { var me = this, publishersByEvent = Ext.event.publisher.Publisher.publishersByEvent, domEvents = me.handledDomEvents, ln = domEvents.length, i = 0, eventName; for (; i < ln; i++) { eventName = domEvents[i]; me.handles[eventName] = 1; publishersByEvent[eventName] = me; } this.callParent(); }, onReady: function() { var me = this, domEvents = me.handledDomEvents, ln, i; if (domEvents) { for (i = 0 , ln = domEvents.length; i < ln; i++) { me.addDelegatedListener(domEvents[i]); } } Ext.getWin().on('unload', me.destroy, me); }, initHandlers: function() { var me = this; me.onDelegatedEvent = Ext.bind(me.onDelegatedEvent, me); me.onDirectEvent = Ext.bind(me.onDirectEvent, me); me.onDirectCaptureEvent = Ext.bind(me.onDirectCaptureEvent, me); }, addDelegatedListener: function(eventName) { this.delegatedListeners[eventName] = 1; this.target.addEventListener(eventName, this.onDelegatedEvent, !!this.captureEvents[eventName]); }, removeDelegatedListener: function(eventName) { delete this.delegatedListeners[eventName]; this.target.removeEventListener(eventName, this.onDelegatedEvent, !!this.captureEvents[eventName]); }, addDirectListener: function(eventName, element, capture) { element.dom.addEventListener(eventName, capture ? this.onDirectCaptureEvent : this.onDirectEvent, capture); }, removeDirectListener: function(eventName, element, capture) { element.dom.removeEventListener(eventName, capture ? this.onDirectCaptureEvent : this.onDirectEvent, capture); }, subscribe: function(element, eventName, delegated, capture) { var me = this, subscribers, id; if (delegated && !me.directEvents[eventName]) { subscribers = capture ? me.captureSubscribers : me.bubbleSubscribers; if (!me.handles[eventName] && !me.delegatedListeners[eventName]) { me.addDelegatedListener(eventName); } if (subscribers[eventName]) { ++subscribers[eventName]; } else { subscribers[eventName] = 1; } } else { subscribers = capture ? me.directCaptureSubscribers : me.directSubscribers; id = element.id; subscribers = subscribers[eventName] || (subscribers[eventName] = {}); if (subscribers[id]) { ++subscribers[id]; } else { subscribers[id] = 1; me.addDirectListener(eventName, element, capture); } } }, unsubscribe: function(element, eventName, delegated, capture) { var me = this, captureSubscribers, bubbleSubscribers, subscribers, id; if (delegated && !me.directEvents[eventName]) { captureSubscribers = me.captureSubscribers; bubbleSubscribers = me.bubbleSubscribers; subscribers = capture ? captureSubscribers : bubbleSubscribers; if (subscribers[eventName]) { --subscribers[eventName]; } if (!me.handles[eventName] && !bubbleSubscribers[eventName] && !captureSubscribers[eventName]) { this.removeDelegatedListener(eventName); } } else { subscribers = capture ? me.directCaptureSubscribers : me.directSubscribers; id = element.id; subscribers = subscribers[eventName]; if (subscribers[id]) { --subscribers[id]; } if (!subscribers[id]) { delete subscribers[id]; me.removeDirectListener(eventName, element, capture); } } }, getPropagatingTargets: function(target) { var currentNode = target, targets = [], parentNode; while (currentNode) { targets.push(currentNode); parentNode = currentNode.parentNode; if (!parentNode) { parentNode = currentNode.defaultView; } currentNode = parentNode; } return targets; }, publish: function(eventName, target, e) { var me = this, targets, el, i, ln; if (Ext.isArray(target)) { targets = target; } else if (me.captureEvents[eventName]) { el = Ext.cache[target.id]; targets = el ? [ el ] : []; } else { targets = me.getPropagatingTargets(target); } ln = targets.length; if (me.captureSubscribers[eventName]) { for (i = ln; i--; ) { el = Ext.cache[targets[i].id]; if (el) { me.fire(el, eventName, e, false, true); if (e.isStopped) { break; } } } } if (!e.isStopped && me.bubbleSubscribers[eventName]) { for (i = 0; i < ln; i++) { el = Ext.cache[targets[i].id]; if (el) { me.fire(el, eventName, e, false, false); if (e.isStopped) { break; } } } } }, fire: function(element, eventName, e, direct, capture) { var event; if (element.hasListeners[eventName]) { event = element.events[eventName]; if (event) { if (capture && direct) { event = event.directCaptures; } else if (capture) { event = event.captures; } else if (direct) { event = event.directs; } if (event) { e.setCurrentTarget(element.dom); event.fire(e, e.target); } } } }, onDelegatedEvent: function(e) { if (Ext.elevateFunction) { Ext.elevateFunction(this.doDelegatedEvent, this, [ e ]); } else { this.doDelegatedEvent(e); } }, doDelegatedEvent: function(e, invokeAfter) { var me = this, timeStamp = e.timeStamp; e = new Ext.event.Event(e); if (me.isEventBlocked(e)) { return false; } me.beforeEvent(e); Ext.frameStartTime = timeStamp; me.reEnterCount++; me.publish(e.type, e.target, e); me.reEnterCount--; if (invokeAfter !== false) { me.afterEvent(e); } return e; }, onDirectEvent: function(e) { if (Ext.elevateFunction) { Ext.elevateFunction(this.doDirectEvent, this, [ e, false ]); } else { this.doDirectEvent(e, false); } }, onDirectCaptureEvent: function(e) { if (Ext.elevateFunction) { Ext.elevateFunction(this.doDirectEvent, this, [ e, true ]); } else { this.doDirectEvent(e, true); } }, doDirectEvent: function(e, capture) { var me = this, currentTarget = e.currentTarget, timeStamp = e.timeStamp; e = new Ext.event.Event(e); if (me.isEventBlocked(e)) { return; } me.beforeEvent(e); Ext.frameStartTime = timeStamp; me.reEnterCount++; me.fire(Ext.cache[currentTarget.id], e.type, e, true, capture); me.reEnterCount--; me.afterEvent(e); }, beforeEvent: function(e) { var browserEvent = e.browserEvent, self = Ext.event.publisher.Dom, touches, touch; if (browserEvent.type === 'touchstart') { touches = browserEvent.touches; if (touches.length === 1) { touch = touches[0]; self.lastTouchStartX = touch.pageX; self.lastTouchStartY = touch.pageY; } } }, afterEvent: function(e) { var browserEvent = e.browserEvent, type = browserEvent.type, self = Ext.event.publisher.Dom, GlobalEvents = Ext.GlobalEvents; if (e.self.pointerEvents[type] && e.pointerType !== 'mouse') { self.lastScreenPointerEventTime = Ext.now(); } if (type === 'touchend') { self.lastTouchEndTime = Ext.now(); } if (!this.reEnterCount && GlobalEvents.hasListeners.idle && !GlobalEvents.idleEventMask[type]) { GlobalEvents.fireEvent('idle'); } }, isEventBlocked: function(e) { var me = this, type = e.type, self = Ext.event.publisher.Dom, now = Ext.now(); return (me.blockedPointerEvents[type] && e.pointerType !== 'mouse') || (me.blockedCompatibilityMouseEvents[type] && (now - self.lastScreenPointerEventTime < 1000)) || (Ext.supports.TouchEvents && e.self.mouseEvents[e.type] && Math.abs(e.pageX - self.lastTouchStartX) < 15 && Math.abs(e.pageY - self.lastTouchStartY) < 15 && (Ext.now() - self.lastTouchEndTime) < 1000); }, destroy: function() { var eventName; for (eventName in this.delegatedListeners) { this.removeDelegatedListener(eventName); } }, reset: function() { var self = Ext.event.publisher.Dom; self.lastScreenPointerEventTime = self.lastTouchEndTime = self.lastTouchStartX = self.lastTouchStartY = undefined; } }, function(Dom) { var doc = document, defaultView = doc.defaultView, prototype = Dom.prototype; if ((Ext.os.is.iOS && Ext.os.version.getMajor() < 5) || Ext.browser.is.AndroidStock || !(defaultView && defaultView.addEventListener)) { prototype.target = doc; } else { prototype.target = defaultView; } Dom.instance = new Dom(); }); Ext.define('Ext.overrides.event.publisher.Dom', { override: 'Ext.event.publisher.Dom' }, function(DomPublisher) { if (Ext.isIE9m) { var docBody = document.body, prototype = DomPublisher.prototype, onDirectEvent, onDirectCaptureEvent; prototype.target = document; prototype.directBoundListeners = {}; onDirectEvent = function(e, publisher, capture) { e.target = e.srcElement || window; e.currentTarget = this; if (capture) { publisher.onDirectCaptureEvent(e); } else { publisher.onDirectEvent(e); } }; onDirectCaptureEvent = function(e, publisher) { e.target = e.srcElement || window; e.currentTarget = this; publisher.onDirectCaptureEvent(e); }; DomPublisher.override({ addDelegatedListener: function(eventName) { this.delegatedListeners[eventName] = 1; this.target.attachEvent('on' + eventName, this.onDelegatedEvent); }, removeDelegatedListener: function(eventName) { delete this.delegatedListeners[eventName]; this.target.detachEvent('on' + eventName, this.onDelegatedEvent); }, addDirectListener: function(eventName, element, capture) { var me = this, dom = element.dom, boundFn = Ext.Function.bind(onDirectEvent, dom, [ me, capture ], true), directBoundListeners = me.directBoundListeners, handlers = directBoundListeners[eventName] || (directBoundListeners[eventName] = {}); handlers[dom.id] = boundFn; if (dom.attachEvent) { dom.attachEvent('on' + eventName, boundFn); } else { me.callParent(arguments); } }, removeDirectListener: function(eventName, element) { var dom = element.dom; if (dom.detachEvent) { dom.detachEvent('on' + eventName, this.directBoundListeners[eventName][dom.id]); } else { this.callParent(arguments); } }, doDelegatedEvent: function(e, invokeAfter) { e.target = e.srcElement || window; if (e.type === 'focusin') { e.relatedTarget = e.fromElement === docBody ? null : e.fromElement; } else if (e.type === 'focusout') { e.relatedTarget = e.toElement === docBody ? null : e.toElement; } return this.callParent([ e, invokeAfter ]); } }); Ext.apply(prototype.directEvents, prototype.captureEvents); prototype.captureEvents = {}; } }); Ext.define('Ext.event.publisher.Gesture', { extend: 'Ext.event.publisher.Dom', requires: [ 'Ext.util.Point', 'Ext.AnimationQueue' ], uses: 'Ext.event.gesture.*', type: 'gesture', config: { async: true }, isCancelEvent: { touchcancel: 1, pointercancel: 1, MSPointerCancel: 1 }, handledEvents: [], handledDomEvents: [], constructor: function(config) { var me = this, handledDomEvents = me.handledDomEvents, supports = Ext.supports, supportsTouchEvents = supports.TouchEvents, Fn = Ext.Function, onTouchStart = me.onTouchStart, onTouchMove = me.onTouchMove, onTouchEnd = me.onTouchEnd, asyncTouchStart = Fn.createAnimationFrame(me.onTouchStart, me, null, 1), asyncTouchMove = Fn.createAnimationFrame(me.onTouchMove, me), asyncTouchEnd = Fn.createAnimationFrame(me.onTouchEnd, me, null, 1); me._handlers = { touchstart: onTouchStart, touchmove: onTouchMove, touchend: onTouchEnd, touchcancel: onTouchEnd, pointerdown: onTouchStart, pointermove: onTouchMove, pointerup: onTouchEnd, pointercancel: onTouchEnd, MSPointerDown: onTouchStart, MSPointerMove: onTouchMove, MSPointerUp: onTouchEnd, MSPointerCancel: onTouchEnd, mousedown: onTouchStart, mousemove: onTouchMove, mouseup: onTouchEnd }; me._asyncHandlers = { touchstart: asyncTouchStart, touchmove: asyncTouchMove, touchend: asyncTouchEnd, touchcancel: asyncTouchEnd, pointerdown: asyncTouchStart, pointermove: asyncTouchMove, pointerup: asyncTouchEnd, pointercancel: asyncTouchEnd, MSPointerDown: asyncTouchStart, MSPointerMove: asyncTouchMove, MSPointerUp: asyncTouchEnd, MSPointerCancel: asyncTouchEnd, mousedown: asyncTouchStart, mousemove: asyncTouchMove, mouseup: asyncTouchEnd }; me.activeTouchesMap = {}; me.activeTouches = []; me.changedTouches = []; me.recognizers = []; if (supportsTouchEvents) { me.onTargetTouchMove = me.onTargetTouchMove.bind(me); me.onTargetTouchEnd = me.onTargetTouchEnd.bind(me); } if (supports.PointerEvents) { handledDomEvents.push('pointerdown', 'pointermove', 'pointerup', 'pointercancel'); me.mousePointerType = 'mouse'; } else if (supports.MSPointerEvents) { handledDomEvents.push('MSPointerDown', 'MSPointerMove', 'MSPointerUp', 'MSPointerCancel'); me.mousePointerType = 4; } else if (supportsTouchEvents) { handledDomEvents.push('touchstart', 'touchmove', 'touchend', 'touchcancel'); } if (!handledDomEvents.length || (supportsTouchEvents && Ext.isWebKit && Ext.os.is.Desktop)) { handledDomEvents.push('mousedown', 'mousemove', 'mouseup'); } me.initConfig(config); return me.callParent(); }, onReady: function() { this.callParent(); Ext.Array.sort(this.recognizers, function(recognizerA, recognizerB) { var a = recognizerA.priority, b = recognizerB.priority; return (a > b) ? 1 : (a < b) ? -1 : 0; }); }, registerRecognizer: function(recognizer) { var me = this, handledEvents = recognizer.handledEvents, ln = handledEvents.length, i; recognizer.setOnRecognized(me.onRecognized); recognizer.setCallbackScope(me); for (i = 0; i < ln; i++) { me.handledEvents.push(handledEvents[i]); } me.registerEvents(handledEvents); me.recognizers.push(recognizer); }, onRecognized: function(eventName, e, info) { var me = this, changedTouches = e.changedTouches, ln = changedTouches.length, targetGroups, targets, i, touch; info = info || {}; info.type = eventName; info.target = changedTouches[0].target; info.isStopped = false; e = e.chain(info); if (ln > 1) { targetGroups = []; for (i = 0; i < ln; i++) { touch = changedTouches[i]; targetGroups.push(touch.targets); } targets = me.getCommonTargets(targetGroups); } else { targets = changedTouches[0].targets; } me.publish(eventName, targets, e); }, getCommonTargets: function(targetGroups) { var firstTargetGroup = targetGroups[0], ln = targetGroups.length; if (ln === 1) { return firstTargetGroup; } var commonTargets = [], i = 1, target, targets, j; while (true) { target = firstTargetGroup[firstTargetGroup.length - i]; if (!target) { return commonTargets; } for (j = 1; j < ln; j++) { targets = targetGroups[j]; if (targets[targets.length - i] !== target) { return commonTargets; } } commonTargets.unshift(target); i++; } return commonTargets; }, invokeRecognizers: function(methodName, e) { var recognizers = this.recognizers, ln = recognizers.length, i, recognizer; if (methodName === 'onStart') { for (i = 0; i < ln; i++) { recognizers[i].isActive = true; } } for (i = 0; i < ln; i++) { recognizer = recognizers[i]; if (recognizer.isActive && recognizer[methodName].call(recognizer, e) === false) { recognizer.isActive = false; } } }, updateTouches: function(e, isEnd) { var me = this, browserEvent = e.browserEvent, touchSources = browserEvent.changedTouches || [ browserEvent ], activeTouches = me.activeTouches, activeTouchesMap = me.activeTouchesMap, changedTouches = [], touchSource, identifier, touch, target, i, ln, x, y; for (i = 0 , ln = touchSources.length; i < ln; i++) { touchSource = touchSources[i]; if ('identifier' in touchSource) { identifier = touchSource.identifier; } else if ('pointerId' in touchSource) { identifier = touchSource.pointerId; } else { identifier = 1; } touch = activeTouchesMap[identifier]; if (!touch) { target = Ext.event.Event.resolveTextNode(touchSource.target); touch = activeTouchesMap[identifier] = { identifier: identifier, target: target, targets: me.getPropagatingTargets(target) }; activeTouches.push(touch); } if (isEnd) { delete activeTouchesMap[identifier]; Ext.Array.remove(activeTouches, touch); } x = touchSource.pageX; y = touchSource.pageY; touch.pageX = x; touch.pageY = y; touch.point = new Ext.util.Point(x, y); changedTouches.push(touch); } e.touches = Ext.Array.clone(activeTouches); e.changedTouches = changedTouches; }, doDelegatedEvent: function(e) { var me = this; e = me.callParent([ e, false ]); if (e) { if (!e.button || e.button < 1) { me.handlers[e.type].call(me, e); } me.afterEvent(e); } }, onTouchStart: function(e) { var me = this, target = e.target; if (e.browserEvent.type === 'touchstart') { target.addEventListener('touchmove', me.onTargetTouchMove); target.addEventListener('touchend', me.onTargetTouchEnd); target.addEventListener('touchcancel', me.onTargetTouchEnd); } me.updateTouches(e); if (!me.isStarted) { me.isStarted = true; me.invokeRecognizers('onStart', e); if (Ext.enableGarbageCollector) { Ext.dom.GarbageCollector.pause(); } } me.invokeRecognizers('onTouchStart', e); }, onTouchMove: function(e) { var me = this, mousePointerType = me.mousePointerType; if (me.isStarted) { if (mousePointerType && e.browserEvent.pointerType === mousePointerType && e.buttons === 0) { e.type = Ext.dom.Element.prototype.eventMap.touchend; e.button = 0; me.onTouchEnd(e); return; } me.updateTouches(e); if (e.changedTouches.length > 0) { me.invokeRecognizers('onTouchMove', e); } } }, onTouchEnd: function(e) { var me = this; if (!me.isStarted) { return; } me.updateTouches(e, true); me.invokeRecognizers(me.isCancelEvent[e.type] ? 'onTouchCancel' : 'onTouchEnd', e); if (!me.activeTouches.length) { me.isStarted = false; me.invokeRecognizers('onEnd', e); if (Ext.enableGarbageCollector) { Ext.dom.GarbageCollector.resume(); } } }, onTargetTouchMove: function(e) { if (Ext.elevateFunction) { Ext.elevateFunction(this.doTargetTouchMove, this, [ e ]); } else { this.doTargetTouchMove(e); } }, doTargetTouchMove: function(e) { if (!Ext.getBody().contains(e.target)) { this.onTouchMove(new Ext.event.Event(e)); } }, onTargetTouchEnd: function(e) { if (Ext.elevateFunction) { Ext.elevateFunction(this.doTargetTouchEnd, this, [ e ]); } else { this.doTargetTouchEnd(e); } }, doTargetTouchEnd: function(e) { var me = this, target = e.target; target.removeEventListener('touchmove', me.onTargetTouchMove); target.removeEventListener('touchend', me.onTargetTouchEnd); target.removeEventListener('touchcancel', me.onTargetTouchEnd); if (!Ext.getBody().contains(target)) { me.onTouchEnd(new Ext.event.Event(e)); } }, updateAsync: function(async) { this.handlers = async ? this._asyncHandlers : this._handlers; }, reset: function() { var me = this, recognizers = me.recognizers, ln = recognizers.length, i, recognizer; me.activeTouchesMap = {}; me.activeTouches = []; me.changedTouches = []; me.isStarted = false; for (i = 0; i < ln; i++) { recognizer = recognizers[i]; recognizer.reset(); recognizer.isActive = false; } this.callParent(); } }, function(Gesture) { Gesture.instance = new Gesture(); }); Ext.define('Ext.overrides.event.publisher.Gesture', { override: 'Ext.event.publisher.Gesture' }, function() { if (Ext.isIE9m) { this.override({ updateTouches: function(e, isEnd) { var browserEvent = e.browserEvent, xy = e.getXY(); browserEvent.pageX = xy[0]; browserEvent.pageY = xy[1]; this.callParent([ e, isEnd ]); }, doDelegatedEvent: function(e) { this.callParent([ Ext.event.Event.enableIEAsync(e) ]); } }); } }); Ext.define('Ext.event.publisher.Focus', { extend: 'Ext.event.publisher.Dom', type: 'focus', handledEvents: [ 'focusenter', 'focusleave' ], handledDomEvents: [ 'focusin', 'focusout' ], doDelegatedEvent: function(e, invokeAfter) { var me = this, relatedTarget; e = me.callParent([ e, false ]); if (e) { if (e.type === 'focusout') { if (e.relatedTarget == null) { me.processFocusIn(e, e.target, document.body, invokeAfter); } } else { relatedTarget = e.relatedTarget; me.processFocusIn(e, (relatedTarget == null || !relatedTarget.tagName) ? document.body : relatedTarget, e.target, invokeAfter); } } }, processFocusIn: function(e, fromElement, toElement, invokeAfter) { var me = this, commonAncestor = Ext.Element.getCommonAncestor(toElement, fromElement, true), node, targets = [], event; for (node = fromElement; node && node !== commonAncestor; node = node.parentNode) { targets.push(node); } if (targets.length) { event = me.createSyntheticEvent('focusleave', e, fromElement, toElement); me.publish('focusleave', targets, event); targets.length = 0; if (event.isStopped) { return; } } for (node = toElement; node !== commonAncestor; node = node.parentNode) { targets.push(node); } event = me.createSyntheticEvent('focusenter', e, toElement, fromElement); me.publish('focusenter', targets, event); if (event.isStopped) { return; } if (invokeAfter) { me.afterEvent(e); } Ext.GlobalEvents.fireEvent('focus', { event: event, toElement: toElement, fromElement: fromElement }); }, createSyntheticEvent: function(eventName, browserEvent, target, relatedTarget) { var event = new Ext.event.Event(browserEvent); event.type = eventName; event.relatedTarget = relatedTarget; event.target = target; return event; } }, function(Focus) { var focusTimeout; if (!Ext.supports.FocusinFocusoutEvents) { this.override({ handledDomEvents: [ 'focus', 'blur' ], doDelegatedEvent: function(e, invokeAfter) { var me = this; e = me.callSuper([ e, false ]); if (e) { clearTimeout(focusTimeout); focusTimeout = 0; if (e.type === 'blur') { var blurredEl = e.target === window ? document.body : e.target; focusTimeout = setTimeout(function() { focusTimeout = 0; me.processFocusIn(e, blurredEl, document.body, invokeAfter); Focus.previousActiveElement = null; }, 0); if (e.target === window || e.target === document) { Focus.previousActiveElement = null; } else { Focus.previousActiveElement = e.target; } } else { me.processFocusIn(e, Focus.previousActiveElement || document.body, e.target === window ? document.body : e.target, invokeAfter); } } } }); } Focus.instance = new Focus(); }); Ext.define('Ext.mixin.Templatable', { extend: 'Ext.Mixin', mixinConfig: { id: 'templatable' }, referenceAttributeName: 'reference', referenceSelector: '[reference]', getElementConfig: function() { return { reference: 'element' }; }, getElementTemplate: function() { var elementTemplate = document.createDocumentFragment(); elementTemplate.appendChild(Ext.Element.create(this.getElementConfig(), true)); return elementTemplate; }, initElement: function() { var prototype = this.self.prototype; prototype.elementTemplate = this.getElementTemplate(); prototype.initElement = prototype.doInitElement; this.initElement.apply(this, arguments); }, linkElement: function(reference, node) { this.link(reference, node); }, doInitElement: function() { var referenceAttributeName = this.referenceAttributeName, renderElement, referenceNodes, i, ln, referenceNode, reference; renderElement = this.elementTemplate.cloneNode(true); referenceNodes = renderElement.querySelectorAll(this.referenceSelector); for (i = 0 , ln = referenceNodes.length; i < ln; i++) { referenceNode = referenceNodes[i]; reference = referenceNode.getAttribute(referenceAttributeName); referenceNode.removeAttribute(referenceAttributeName); this.linkElement(reference, referenceNode); } } }); Ext.define('Ext.TaskQueue', { requires: 'Ext.AnimationQueue', singleton: true, pending: false, mode: true, constructor: function() { this.readQueue = []; this.writeQueue = []; this.run = Ext.Function.bind(this.run, this); if (Ext.os.is.iOS) { Ext.interval(this.watch, 500, this); } }, requestRead: function(fn, scope, args) { this.request(true); this.readQueue.push(arguments); }, requestWrite: function(fn, scope, args) { this.request(false); this.writeQueue.push(arguments); }, request: function(mode) { if (!this.pending) { this.pendingTime = Date.now(); this.pending = true; this.mode = mode; if (mode) { Ext.defer(this.run, 1, this); } else { Ext.Function.requestAnimationFrame(this.run); } } }, watch: function() { if (this.pending && Date.now() - this.pendingTime >= 500) { this.run(); } }, run: function() { this.pending = false; var readQueue = this.readQueue, writeQueue = this.writeQueue, request = null, queue; if (this.mode) { queue = readQueue; if (writeQueue.length > 0) { request = false; } } else { queue = writeQueue; if (readQueue.length > 0) { request = true; } } var tasks = queue.slice(), i, ln, task, fn, scope; queue.length = 0; for (i = 0 , ln = tasks.length; i < ln; i++) { task = tasks[i]; fn = task[0]; scope = task[1]; if (typeof fn === 'string') { fn = scope[fn]; } if (task.length > 2) { fn.apply(scope, task[2]); } else { fn.call(scope); } } tasks.length = 0; if (request !== null) { this.request(request); } } }); Ext.define('Ext.util.sizemonitor.Abstract', { mixins: [ 'Ext.mixin.Templatable' ], requires: [ 'Ext.TaskQueue' ], config: { element: null, callback: Ext.emptyFn, scope: null, args: [] }, width: 0, height: 0, contentWidth: 0, contentHeight: 0, constructor: function(config) { this.refresh = Ext.Function.bind(this.refresh, this); this.info = { width: 0, height: 0, contentWidth: 0, contentHeight: 0, flag: 0 }; this.initElement(); this.initConfig(config); this.bindListeners(true); }, bindListeners: Ext.emptyFn, applyElement: function(element) { if (element) { return Ext.get(element); } }, updateElement: function(element) { element.append(this.detectorsContainer); element.addCls(Ext.baseCSSPrefix + 'size-monitored'); }, applyArgs: function(args) { return args.concat([ this.info ]); }, refreshMonitors: Ext.emptyFn, forceRefresh: function() { Ext.TaskQueue.requestRead('refresh', this); }, getContentBounds: function() { return this.detectorsContainer.getBoundingClientRect(); }, getContentWidth: function() { return this.detectorsContainer.offsetWidth; }, getContentHeight: function() { return this.detectorsContainer.offsetHeight; }, refreshSize: function() { var element = this.getElement(); if (!element || element.isDestroyed) { return false; } var width = element.getWidth(), height = element.getHeight(), contentWidth = this.getContentWidth(), contentHeight = this.getContentHeight(), currentContentWidth = this.contentWidth, currentContentHeight = this.contentHeight, info = this.info, resized = false, flag; this.width = width; this.height = height; this.contentWidth = contentWidth; this.contentHeight = contentHeight; flag = ((currentContentWidth !== contentWidth ? 1 : 0) + (currentContentHeight !== contentHeight ? 2 : 0)); if (flag > 0) { info.width = width; info.height = height; info.contentWidth = contentWidth; info.contentHeight = contentHeight; info.flag = flag; resized = true; this.getCallback().apply(this.getScope(), this.getArgs()); } return resized; }, refresh: function(force) { if (this.refreshSize() || force) { Ext.TaskQueue.requestWrite('refreshMonitors', this); } }, destroy: function() { var element = this.getElement(); this.bindListeners(false); if (element && !element.isDestroyed) { element.removeCls(Ext.baseCSSPrefix + 'size-monitored'); } delete this._element; this.callParent(); } }); Ext.define('Ext.util.sizemonitor.Default', { extend: 'Ext.util.sizemonitor.Abstract', updateElement: function(element) {}, bindListeners: function(bind) { var element = this.getElement().dom; if (!element) { return; } if (bind) { element.onresize = this.refresh; } else { delete element.onresize; } }, getContentBounds: function() { return this.getElement().dom.getBoundingClientRect(); }, getContentWidth: function() { return this.getElement().getWidth(); }, getContentHeight: function() { return this.getElement().getHeight(); } }); Ext.define('Ext.util.sizemonitor.Scroll', { extend: 'Ext.util.sizemonitor.Abstract', getElementConfig: function() { return { reference: 'detectorsContainer', classList: [ Ext.baseCSSPrefix + 'size-monitors', 'scroll' ], children: [ { reference: 'expandMonitor', className: 'expand' }, { reference: 'shrinkMonitor', className: 'shrink' } ] }; }, constructor: function(config) { this.onScroll = Ext.Function.bind(this.onScroll, this); this.callParent(arguments); }, bindListeners: function(bind) { var method = bind ? 'addEventListener' : 'removeEventListener'; this.expandMonitor[method]('scroll', this.onScroll, true); this.shrinkMonitor[method]('scroll', this.onScroll, true); }, forceRefresh: function() { Ext.TaskQueue.requestRead('refresh', this, [ true ]); }, onScroll: function() { Ext.TaskQueue.requestRead('refresh', this); }, refreshMonitors: function() { var expandMonitor = this.expandMonitor, shrinkMonitor = this.shrinkMonitor, end = 1000000; if (expandMonitor && !expandMonitor.isDestroyed) { expandMonitor.scrollLeft = end; expandMonitor.scrollTop = end; } if (shrinkMonitor && !shrinkMonitor.isDestroyed) { shrinkMonitor.scrollLeft = end; shrinkMonitor.scrollTop = end; } } }); Ext.define('Ext.util.sizemonitor.OverflowChange', { extend: 'Ext.util.sizemonitor.Abstract', constructor: function(config) { this.onExpand = Ext.Function.bind(this.onExpand, this); this.onShrink = Ext.Function.bind(this.onShrink, this); this.callParent(arguments); }, getElementConfig: function() { return { reference: 'detectorsContainer', classList: [ Ext.baseCSSPrefix + 'size-monitors', 'overflowchanged' ], children: [ { reference: 'expandMonitor', className: 'expand', children: [ { reference: 'expandHelper' } ] }, { reference: 'shrinkMonitor', className: 'shrink', children: [ { reference: 'shrinkHelper' } ] } ] }; }, bindListeners: function(bind) { var method = bind ? 'addEventListener' : 'removeEventListener'; this.expandMonitor[method](Ext.browser.is.Firefox ? 'underflow' : 'overflowchanged', this.onExpand, true); this.shrinkMonitor[method](Ext.browser.is.Firefox ? 'overflow' : 'overflowchanged', this.onShrink, true); }, onExpand: function(e) { if (Ext.browser.is.Webkit && e.horizontalOverflow && e.verticalOverflow) { return; } Ext.TaskQueue.requestRead('refresh', this); }, onShrink: function(e) { if (Ext.browser.is.Webkit && !e.horizontalOverflow && !e.verticalOverflow) { return; } Ext.TaskQueue.requestRead('refresh', this); }, refreshMonitors: function() { if (this.isDestroyed) { return; } var expandHelper = this.expandHelper, shrinkHelper = this.shrinkHelper, contentBounds = this.getContentBounds(), width = contentBounds.width, height = contentBounds.height, style; if (expandHelper && !expandHelper.isDestroyed) { style = expandHelper.style; style.width = (width + 1) + 'px'; style.height = (height + 1) + 'px'; } if (shrinkHelper && !shrinkHelper.isDestroyed) { style = shrinkHelper.style; style.width = width + 'px'; style.height = height + 'px'; } Ext.TaskQueue.requestRead('refresh', this); } }); Ext.define('Ext.util.SizeMonitor', { requires: [ 'Ext.util.sizemonitor.Default', 'Ext.util.sizemonitor.Scroll', 'Ext.util.sizemonitor.OverflowChange' ], constructor: function(config) { var namespace = Ext.util.sizemonitor; if (Ext.browser.is.Firefox) { return new namespace.OverflowChange(config); } else if (Ext.browser.is.WebKit) { if (!Ext.browser.is.Silk && Ext.browser.engineVersion.gtEq('535')) { return new namespace.OverflowChange(config); } else { return new namespace.Scroll(config); } } else if (Ext.browser.is.IE11) { return new namespace.Scroll(config); } else { return new namespace.Default(config); } } }); Ext.define('Ext.event.publisher.ElementSize', { extend: 'Ext.event.publisher.Publisher', requires: [ 'Ext.util.SizeMonitor' ], type: 'size', handledEvents: [ 'resize' ], constructor: function() { this.monitors = {}; this.subscribers = {}; this.callParent(arguments); }, subscribe: function(element) { var id = element.id, subscribers = this.subscribers, monitors = this.monitors; if (subscribers[id]) { ++subscribers[id]; } else { subscribers[id] = 1; monitors[id] = new Ext.util.SizeMonitor({ element: element, callback: this.onElementResize, scope: this, args: [ element ] }); } element.on('painted', 'forceRefresh', monitors[id]); return true; }, unsubscribe: function(element) { var id = element.id, subscribers = this.subscribers, monitors = this.monitors, sizeMonitor; if (subscribers[id] && !--subscribers[id]) { delete subscribers[id]; sizeMonitor = monitors[id]; element.un('painted', 'forceRefresh', sizeMonitor); sizeMonitor.destroy(); delete monitors[id]; } }, onElementResize: function(element, info) { Ext.TaskQueue.requestRead('fire', this, [ element, 'resize', [ element, info ] ]); } }, function(ElementSize) { ElementSize.instance = new ElementSize(); }); Ext.define('Ext.util.paintmonitor.Abstract', { config: { element: null, callback: Ext.emptyFn, scope: null, args: [] }, eventName: '', monitorClass: '', constructor: function(config) { this.onElementPainted = Ext.Function.bind(this.onElementPainted, this); this.initConfig(config); }, bindListeners: function(bind) { this.monitorElement[bind ? 'addEventListener' : 'removeEventListener'](this.eventName, this.onElementPainted, true); }, applyElement: function(element) { if (element) { return Ext.get(element); } }, updateElement: function(element) { this.monitorElement = Ext.Element.create({ classList: [ Ext.baseCSSPrefix + 'paint-monitor', this.monitorClass ] }, true); element.appendChild(this.monitorElement); element.addCls(Ext.baseCSSPrefix + 'paint-monitored'); this.bindListeners(true); }, onElementPainted: function() {}, destroy: function() { var monitorElement = this.monitorElement, parentNode = monitorElement.parentNode, element = this.getElement(); this.bindListeners(false); delete this.monitorElement; if (element && !element.isDestroyed) { element.removeCls(Ext.baseCSSPrefix + 'paint-monitored'); delete this._element; } if (parentNode) { parentNode.removeChild(monitorElement); } this.callParent(); } }); Ext.define('Ext.util.paintmonitor.CssAnimation', { extend: 'Ext.util.paintmonitor.Abstract', eventName: Ext.browser.is.WebKit ? 'webkitAnimationEnd' : 'animationend', monitorClass: 'cssanimation', onElementPainted: function(e) { if (e.animationName === Ext.baseCSSPrefix + 'paint-monitor-helper') { this.getCallback().apply(this.getScope(), this.getArgs()); } } }); Ext.define('Ext.util.paintmonitor.OverflowChange', { extend: 'Ext.util.paintmonitor.Abstract', eventName: Ext.browser.is.Firefox ? 'overflow' : 'overflowchanged', monitorClass: 'overflowchange', onElementPainted: function(e) { this.getCallback().apply(this.getScope(), this.getArgs()); } }); Ext.define('Ext.util.PaintMonitor', { requires: [ 'Ext.util.paintmonitor.CssAnimation', 'Ext.util.paintmonitor.OverflowChange' ], constructor: function(config) { if (Ext.browser.is.Firefox || (Ext.browser.is.WebKit && Ext.browser.engineVersion.gtEq('536') && !Ext.os.is.Blackberry)) { return new Ext.util.paintmonitor.OverflowChange(config); } else { return new Ext.util.paintmonitor.CssAnimation(config); } } }); Ext.define('Ext.event.publisher.ElementPaint', { extend: 'Ext.event.publisher.Publisher', requires: [ 'Ext.util.PaintMonitor', 'Ext.TaskQueue' ], type: 'paint', handledEvents: [ 'painted' ], constructor: function() { this.monitors = {}; this.subscribers = {}; this.callParent(arguments); }, subscribe: function(element) { var id = element.id, subscribers = this.subscribers; if (subscribers[id]) { ++subscribers[id]; } else { subscribers[id] = 1; this.monitors[id] = new Ext.util.PaintMonitor({ element: element, callback: this.onElementPainted, scope: this, args: [ element ] }); } }, unsubscribe: function(element) { var id = element.id, subscribers = this.subscribers, monitors = this.monitors; if (subscribers[id] && !--subscribers[id]) { delete subscribers[id]; monitors[id].destroy(); delete monitors[id]; } }, onElementPainted: function(element) { Ext.TaskQueue.requestRead('fire', this, [ element, 'painted', [ element ] ]); } }, function(ElementPaint) { ElementPaint.instance = new ElementPaint(); }); Ext.define('Ext.dom.Element', function(Element) { var WIN = window, DOC = document, windowId = 'ext-window', documentId = 'ext-document', WIDTH = 'width', HEIGHT = 'height', MIN_WIDTH = 'min-width', MIN_HEIGHT = 'min-height', MAX_WIDTH = 'max-width', MAX_HEIGHT = 'max-height', TOP = 'top', RIGHT = 'right', BOTTOM = 'bottom', LEFT = 'left', VISIBILITY = 'visibility', HIDDEN = 'hidden', DISPLAY = "display", NONE = "none", ZINDEX = "z-index", POSITION = "position", RELATIVE = "relative", STATIC = "static", SEPARATOR = '-', wordsRe = /\w/g, spacesRe = /\s+/, classNameSplitRegex = /[\s]+/, transparentRe = /^(?:transparent|(?:rgba[(](?:\s*\d+\s*[,]){3}\s*0\s*[)]))$/i, adjustDirect2DTableRe = /table-row|table-.*-group/, topRe = /top/i, borders = { t: 'border-top-width', r: 'border-right-width', b: 'border-bottom-width', l: 'border-left-width' }, paddings = { t: 'padding-top', r: 'padding-right', b: 'padding-bottom', l: 'padding-left' }, margins = { t: 'margin-top', r: 'margin-right', b: 'margin-bottom', l: 'margin-left' }, paddingsTLRB = [ paddings.l, paddings.r, paddings.t, paddings.b ], bordersTLRB = [ borders.l, borders.r, borders.t, borders.b ], numberRe = /\d+$/, unitRe = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i, defaultUnit = 'px', camelRe = /(-[a-z])/gi, cssRe = /([a-z0-9\-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi, pxRe = /^\d+(?:\.\d*)?px$/i, propertyCache = {}, camelReplaceFn = function(m, a) { return a.charAt(1).toUpperCase(); }, visibilityCls = Ext.baseCSSPrefix + 'hidden-visibility', displayCls = Ext.baseCSSPrefix + 'hidden-display', offsetsCls = Ext.baseCSSPrefix + 'hidden-offsets', sizedCls = Ext.baseCSSPrefix + 'sized', unsizedCls = Ext.baseCSSPrefix + 'unsized', stretchedCls = Ext.baseCSSPrefix + 'stretched', noTouchScrollCls = Ext.baseCSSPrefix + 'no-touch-scroll', CREATE_ATTRIBUTES = { style: 'style', className: 'className', cls: 'cls', classList: 'classList', text: 'text', hidden: 'hidden', html: 'html', children: 'children' }, visFly, scrollFly, caFly; return { alternateClassName: [ 'Ext.Element' ], mixins: [ 'Ext.util.Positionable', 'Ext.mixin.Observable' ], requires: [ 'Ext.dom.Shadow', 'Ext.dom.Shim', 'Ext.dom.ElementEvent', 'Ext.event.publisher.Dom', 'Ext.event.publisher.Gesture', 'Ext.event.publisher.Focus', 'Ext.event.publisher.ElementSize', 'Ext.event.publisher.ElementPaint' ], uses: [ 'Ext.dom.Helper', 'Ext.dom.CompositeElement', 'Ext.dom.Fly' ], observableType: 'element', isElement: true, skipGarbageCollection: true, identifiablePrefix: 'ext-element-', styleHooks: {}, validIdRe: Ext.validIdRe, blockedEvents: Ext.supports.EmulatedMouseOver ? { mouseover: 1 } : {}, longpressEvents: { longpress: 1, taphold: 1 }, constructor: function(dom) { var me = this, id; if (typeof dom === 'string') { dom = DOC.getElementById(dom); } if (!dom) { Ext.Error.raise("Invalid domNode reference or an id of an existing domNode: " + dom); return null; } if (Ext.cache[dom.id]) { Ext.Error.raise("Element cache already contains an entry for id '" + dom.id + "'. Use Ext.get() to create or retrieve Element instances."); } me.dom = dom; id = dom.id; if (id) { me.id = id; } else { id = dom.id = me.getUniqueId(); } if (!me.validIdRe.test(me.id)) { Ext.Error.raise('Invalid Element "id": "' + me.id + '"'); } me.el = me; Ext.cache[id] = me; me.mixins.observable.constructor.call(me); }, inheritableStatics: { cache: Ext.cache = {}, VISIBILITY: 1, DISPLAY: 2, OFFSETS: 3, unitRe: unitRe, useDelegatedEvents: true, validNodeTypes: { 1: 1, 9: 1 }, addUnits: function(size, units) { if (typeof size === 'number') { return size + (units || defaultUnit); } if (size === "" || size === "auto" || size == null) { return size || ''; } if (numberRe.test(size)) { return size + (units || defaultUnit); } if (!unitRe.test(size)) { Ext.Logger.warn("Warning, size detected (" + size + ") not a valid property value on Element.addUnits."); return size || ''; } return size; }, create: function(attributes, domNode) { var me = this, hidden = CREATE_ATTRIBUTES.hidden, element, elementStyle, tag, value, name, i, ln, className; if (!attributes) { attributes = {}; } if (attributes.isElement) { return domNode ? attributes.dom : attributes; } else if ('nodeType' in attributes) { return domNode ? attributes : Ext.get(attributes); } if (typeof attributes === 'string') { return DOC.createTextNode(attributes); } tag = attributes.tag; if (!tag) { tag = 'div'; } if (attributes.namespace) { element = DOC.createElementNS(attributes.namespace, tag); } else { element = DOC.createElement(tag); } elementStyle = element.style; if (attributes[hidden]) { className = attributes.className; className = (className == null) ? '' : className + ' '; attributes.className = className + displayCls; delete attributes[hidden]; } for (name in attributes) { if (name !== 'tag') { value = attributes[name]; switch (name) { case CREATE_ATTRIBUTES.style: if (typeof value === 'string') { element.setAttribute(name, value); } else { for (i in value) { if (value.hasOwnProperty(i)) { elementStyle[i] = value[i]; } } }; break; case CREATE_ATTRIBUTES.className: case CREATE_ATTRIBUTES.cls: element.className = value; break; case CREATE_ATTRIBUTES.classList: element.className = value.join(' '); break; case CREATE_ATTRIBUTES.text: element.textContent = value; break; case CREATE_ATTRIBUTES.html: element.innerHTML = value; break; case CREATE_ATTRIBUTES.children: for (i = 0 , ln = value.length; i < ln; i++) { element.appendChild(me.create(value[i], true)); }; break; default: if (value != null) { element.setAttribute(name, value); }; } } } if (domNode) { return element; } else { return me.get(element); } }, detach: function() { var dom = this.dom; if (dom && dom.parentNode && dom.tagName !== 'BODY') { dom.parentNode.removeChild(dom); } return this; }, fly: function(dom, named) { return Ext.fly(dom, named); }, fromPoint: function(x, y) { return Ext.get(DOC.elementFromPoint(x, y)); }, get: function(el) { var me = this, cache = Ext.cache, nodeType, dom, id, entry, isDoc, isWin, isValidNodeType; if (!el) { return null; } function warnDuplicate(id) { Ext.Error.raise("DOM element with id " + id + " in Element cache is not the same as element in the DOM. " + "Make sure to clean up Element instances using destroy()"); } if (el.isFly) { el = el.dom; } if (typeof el === 'string') { id = el; if (cache.hasOwnProperty(id)) { entry = cache[id]; if (entry.skipGarbageCollection || !Ext.isGarbage(entry.dom)) { dom = Ext.getElementById ? Ext.getElementById(id) : DOC.getElementById(id); if (dom && (dom !== entry.dom)) { warnDuplicate(id); } return entry; } else { entry.destroy(); } } if (id === windowId) { return Element.get(WIN); } else if (id === documentId) { return Element.get(DOC); } dom = Ext.getElementById ? Ext.getElementById(id) : DOC.getElementById(id); if (dom) { return new Element(dom); } } nodeType = el.nodeType; if (nodeType) { isDoc = (nodeType === 9); isValidNodeType = me.validNodeTypes[nodeType]; } else { isWin = (el.window == el); } if (isValidNodeType || isWin) { id = el.id; if (cache.hasOwnProperty(id)) { entry = cache[id]; if (entry.skipGarbageCollection || el === entry.dom || !Ext.isGarbage(entry.dom)) { if (el !== entry.dom) { warnDuplicate(id); } return entry; } else { entry.destroy(); } } if (el === DOC) { el.id = documentId; } if (el == WIN) { el.id = windowId; } el = new Element(el); if (isWin || isDoc) { el.skipGarbageCollection = true; } return el; } if (el.isElement) { return el; } if (el.isComposite) { return el; } if (Ext.isIterable(el)) { return me.select(el); } return null; }, getActiveElement: function() { var active = DOC.activeElement; if (!active || !active.focus) { active = DOC.body; } return active; }, getDocumentHeight: function() { return Math.max(!Ext.isStrict ? DOC.body.scrollHeight : DOC.documentElement.scrollHeight, this.getViewportHeight()); }, getDocumentWidth: function() { return Math.max(!Ext.isStrict ? DOC.body.scrollWidth : DOC.documentElement.scrollWidth, this.getViewportWidth()); }, getOrientation: function() { if (Ext.supports.OrientationChange) { return (WIN.orientation == 0) ? 'portrait' : 'landscape'; } return (WIN.innerHeight > WIN.innerWidth) ? 'portrait' : 'landscape'; }, getViewportHeight: function() { return WIN.innerHeight; }, getViewportWidth: function() { return WIN.innerWidth; }, getViewSize: function() { return { width: Element.getViewportWidth(), height: Element.getViewportHeight() }; }, normalize: function(prop) { return propertyCache[prop] || (propertyCache[prop] = prop.replace(camelRe, camelReplaceFn)); }, parseBox: function(box) { box = box || 0; var type = typeof box, parts, ln; if (type === 'number') { return { top: box, right: box, bottom: box, left: box }; } else if (type !== 'string') { return box; } 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 }; }, parseStyles: function(styles) { var out = {}, matches; if (styles) { cssRe.lastIndex = 0; while ((matches = cssRe.exec(styles))) { out[matches[1]] = matches[2] || ''; } } return out; }, select: function(selector, composite, root) { return Ext.fly(root || DOC).select(selector, composite); }, query: function(selector, asDom, root) { return Ext.fly(root || DOC).query(selector, asDom); }, unitizeBox: function(box, units) { var me = this; box = me.parseBox(box); return me.addUnits(box.top, units) + ' ' + me.addUnits(box.right, units) + ' ' + me.addUnits(box.bottom, units) + ' ' + me.addUnits(box.left, units); }, serializeForm: function(form) { var fElements = form.elements || (DOC.forms[form] || Ext.getDom(form)).elements, hasSubmit = false, encoder = encodeURIComponent, data = '', eLen = fElements.length, element, name, type, options, hasValue, e, o, oLen, opt; for (e = 0; e < eLen; e++) { element = fElements[e]; name = element.name; type = element.type; options = element.options; if (!element.disabled && name) { if (/select-(one|multiple)/i.test(type)) { oLen = options.length; for (o = 0; o < oLen; o++) { opt = options[o]; if (opt.selected) { hasValue = opt.hasAttribute('value'); data += Ext.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); }, getCommonAncestor: function(nodeA, nodeB, returnDom) { caFly = caFly || new Ext.dom.Fly(); caFly.attach(Ext.getDom(nodeA)); while (!caFly.isAncestor(nodeB)) { if (caFly.dom.parentNode) { caFly.attach(caFly.dom.parentNode); } else { caFly.attach(document.body); break; } } return returnDom ? caFly.dom : Ext.get(caFly); } }, addCls: function(names, prefix, suffix) { var me = this, elementData = me.getData(), hasNewCls, dom, map, classList, i, ln, name; if (!names) { return me; } if (!elementData.isSynchronized) { me.synchronize(); } dom = me.dom; map = elementData.classMap; classList = elementData.classList; prefix = prefix ? prefix + SEPARATOR : ''; suffix = suffix ? SEPARATOR + suffix : ''; if (typeof names === 'string') { names = names.split(spacesRe); } for (i = 0 , ln = names.length; i < ln; i++) { name = names[i]; if (name) { name = prefix + name + suffix; if (!map[name]) { map[name] = true; classList.push(name); hasNewCls = true; } } } if (hasNewCls) { dom.className = classList.join(' '); } return me; }, addStyles: function(sides, styles) { var totalSize = 0, sidesArr = (sides || '').match(wordsRe), i, len = sidesArr.length, side, styleSides = []; if (len === 1) { totalSize = Math.abs(parseFloat(this.getStyle(styles[sidesArr[0]])) || 0); } else if (len) { for (i = 0; i < len; i++) { side = sidesArr[i]; styleSides.push(styles[side]); } styleSides = this.getStyle(styleSides); for (i = 0; i < len; i++) { side = sidesArr[i]; totalSize += parseFloat(styleSides[styles[side]]) || 0; } } return totalSize; }, addUnits: function(size, units) { return Element.addUnits(size, units); }, 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, currentStyle = dom.currentStyle, floating; if (display === 'inline') { dom.style.display = 'inline-block'; } dom.style.position = display.match(adjustDirect2DTableRe) ? 'absolute' : 'static'; floating = (parseFloat(currentStyle[dimension]) || parseFloat(currentStyle.msTransformOrigin.split(' ')[originIndex]) * 2) % 1; dom.style.position = inlinePosition; if (display === 'inline') { dom.style.display = inlineDisplay; } return floating; }, animate: function(animation) { animation = new Ext.fx.Animation(animation); animation.setElement(this); this._activeAnimation = animation; animation.on({ animationend: this._onAnimationEnd }); Ext.Animator.run(animation); }, _onAnimationEnd: function() { this._activeAnimation = null; }, getActiveAnimation: function() { return this._activeAnimation; }, append: function() { this.appendChild.apply(this, arguments); }, appendChild: function(el, returnDom) { var me = this, insertEl, eLen, e; if (el.nodeType || el.dom || typeof el === 'string') { el = Ext.getDom(el); me.dom.appendChild(el); return !returnDom ? Ext.get(el) : el; } else if (el.length) { insertEl = Ext.fly(document.createDocumentFragment()); eLen = el.length; for (e = 0; e < eLen; e++) { insertEl.appendChild(el[e], returnDom); } me.dom.appendChild(insertEl.dom); return returnDom ? insertEl.dom : insertEl; } else { return me.createChild(el, null, returnDom); } }, appendTo: function(el) { Ext.getDom(el).appendChild(this.dom); return this; }, applyStyles: function(styles) { if (styles) { if (typeof styles === "function") { styles = styles.call(); } if (typeof styles === "string") { styles = Element.parseStyles(styles); } if (typeof styles === "object") { this.setStyle(styles); } } return this; }, blur: function() { var me = this, dom = me.dom; if (dom !== DOC.body) { try { dom.blur(); } catch (e) {} return me; } else { return me.focus(undefined, dom); } }, cacheScrollValues: function() { var me = this, scrollValues = [], scrolledDescendants = [], descendants, descendant, i, len; scrollFly = scrollFly || new Ext.dom.Fly(); descendants = me.query('*'); for (i = 0 , len = descendants.length; i < len; i++) { descendant = descendants[i]; if (descendant.scrollTop > 0 || descendant.scrollLeft !== 0) { scrolledDescendants.push(descendant); scrollValues.push(scrollFly.attach(descendant).getScroll()); } } return function() { var scroll, i, len; for (i = 0 , len = scrolledDescendants.length; i < len; i++) { scroll = scrollValues[i]; scrollFly.attach(scrolledDescendants[i]); scrollFly.setScrollLeft(scroll.left); scrollFly.setScrollTop(scroll.top); } }; }, center: function(centerIn) { return this.alignTo(centerIn || DOC, 'c-c'); }, child: function(selector, returnDom) { var me = this, id = Ext.get(me).id; return me.selectNode(Ext.makeIdSelector(id) + " > " + selector, !!returnDom); }, constrainScrollLeft: function(left) { var dom = this.dom; return Math.max(Math.min(left, dom.scrollWidth - dom.clientWidth), 0); }, constrainScrollTop: function(top) { var dom = this.dom; return Math.max(Math.min(top, dom.scrollHeight - dom.clientHeight), 0); }, createChild: function(config, insertBefore, returnDom) { config = config || { tag: 'div' }; if (insertBefore) { return Ext.DomHelper.insertBefore(insertBefore, config, returnDom !== true); } else { return Ext.DomHelper.append(this.dom, config, returnDom !== true); } }, contains: function(element) { if (!element) { return false; } var me = this, dom = Ext.getDom(element); return (dom === me.dom) || me.isAncestor(dom); }, destroy: function() { var me = this, dom = me.dom; if (me.isDestroyed) { Ext.Logger.warn("Cannot destroy Element \"" + me.id + "\". Already destroyed."); return; } if (dom) { if (dom === DOC.body) { Ext.Error.raise("Cannot destroy body element."); } else if (dom === DOC) { Ext.Error.raise("Cannot destroy document object."); } else if (dom === WIN) { Ext.Error.raise("Cannot destroy window object"); } } if (dom && dom.parentNode) { dom.parentNode.removeChild(dom); } me.collect(); }, detach: function() { var dom = this.dom; if (dom && dom.parentNode && dom.tagName !== 'BODY') { dom.parentNode.removeChild(dom); } return this; }, disableShadow: function() { var shadow = this.shadow; if (shadow) { shadow.hide(); shadow.disabled = true; } }, disableShim: function() { var shim = this.shim; if (shim) { shim.hide(); shim.disabled = true; } }, disableTouchContextMenu: function() { this._contextMenuListenerRemover = this.on({ MSHoldVisual: function(e) { e.preventDefault(); }, destroyable: true, delegated: false }); }, disableTouchScroll: function() { this.addCls(noTouchScrollCls); this.on({ touchmove: function(e) { e.preventDefault(); }, translate: false }); }, doReplaceWith: function(element) { var dom = this.dom; dom.parentNode.replaceChild(Ext.getDom(element), dom); }, doScrollIntoView: function(container, hscroll, animate, highlight, getScrollX, scrollTo) { scrollFly = scrollFly || new Ext.dom.Fly(); var me = this, dom = me.dom, scrollX = scrollFly.attach(container)[getScrollX](), scrollY = container.scrollTop, position = me.getScrollIntoViewXY(container, scrollX, scrollY), newScrollX = position.x, newScrollY = position.y; if (highlight) { if (animate) { animate = Ext.apply({ listeners: { afteranimate: function() { scrollFly.attach(dom).highlight(); } } }, animate); } else { scrollFly.attach(dom).highlight(); } } if (newScrollY !== scrollY) { scrollFly.attach(container).scrollTo('top', newScrollY, animate); } if (hscroll !== false && (newScrollX !== scrollX)) { scrollFly.attach(container)[scrollTo]('left', newScrollX, animate); } return me; }, down: function(selector, returnDom) { return this.selectNode(selector, !!returnDom); }, enableShadow: function(options, isVisible) { var me = this, shadow = me.shadow || (me.shadow = new Ext.dom.Shadow(Ext.apply({ target: me }, options))), shim = me.shim; if (shim) { shim.offsets = shadow.outerOffsets; shim.shadow = shadow; shadow.shim = shim; } if (isVisible === true || (isVisible !== false && me.isVisible())) { shadow.show(); } else { shadow.hide(); } shadow.disabled = false; }, enableShim: function(options, isVisible) { var me = this, shim = me.shim || (me.shim = new Ext.dom.Shim(Ext.apply({ target: me }, options))), shadow = me.shadow; if (shadow) { shim.offsets = shadow.outerOffsets; shim.shadow = shadow; shadow.shim = shim; } if (isVisible === true || (isVisible !== false && me.isVisible())) { shim.show(); } else { shim.hide(); } shim.disabled = false; }, findParent: function(simpleSelector, limit, returnEl) { var me = this, target = me.dom, topmost = DOC.documentElement, depth = 0; if (limit || limit === 0) { if (typeof limit !== 'number') { topmost = Ext.getDom(limit); limit = Number.MAX_VALUE; } } else { limit = 50; } while (target && target.nodeType === 1 && depth < limit && target !== topmost) { if (Ext.fly(target).is(simpleSelector)) { return returnEl ? Ext.get(target) : target; } depth++; target = target.parentNode; } return null; }, findParentNode: function(simpleSelector, limit, returnEl) { var p = Ext.fly(this.dom.parentNode); return p ? p.findParent(simpleSelector, limit, returnEl) : null; }, first: function(selector, returnDom) { return this.matchNode('nextSibling', 'firstChild', selector, returnDom); }, focus: function(defer, dom) { var me = this; dom = dom || me.dom; try { if (Number(defer)) { Ext.defer(me.focus, defer, me, [ null, dom ]); } else { Ext.GlobalEvents.fireEvent('beforefocus', dom); dom.focus(); } } catch (e) {} return me; }, collect: function() { var me = this, dom = me.dom, shadow = me.shadow, shim = me.shim; if (!me.isFly) { me.mixins.observable.destroy.call(me); delete Ext.cache[me.id]; me.isDestroyed = true; me.el = null; } if (dom) { dom._extData = me.dom = null; } if (shadow) { shadow.hide(); me.shadow = null; } if (shim) { shim.hide(); me.shim = null; } }, getAnchorToXY: function(el, anchor, local, mySize) { return el.getAnchorXY(anchor, local, mySize); }, getAttribute: function(name, namespace) { var dom = this.dom; return namespace ? (dom.getAttributeNS(namespace, name) || dom.getAttribute(namespace + ":" + name)) : (dom.getAttribute(name) || dom[name] || null); }, getAttributes: function() { var attributes = this.dom.attributes, result = {}, attr, i, len; for (i = 0 , len = attributes.length; i < len; i++) { attr = attributes[i]; result[attr.name] = attr.value; } return result; }, getBottom: function(local) { return (local ? this.getLocalY() : this.getY()) + this.getHeight(); }, getById: function(id, asDom) { var dom = DOC.getElementById(id) || this.dom.querySelector(Ext.makeIdSelector(id)); return asDom ? dom : (dom ? Ext.get(dom) : null); }, getBorderPadding: function() { var paddingWidth = this.getStyle(paddingsTLRB), bordersWidth = this.getStyle(bordersTLRB); return { beforeX: (parseFloat(bordersWidth[borders.l]) || 0) + (parseFloat(paddingWidth[paddings.l]) || 0), afterX: (parseFloat(bordersWidth[borders.r]) || 0) + (parseFloat(paddingWidth[paddings.r]) || 0), beforeY: (parseFloat(bordersWidth[borders.t]) || 0) + (parseFloat(paddingWidth[paddings.t]) || 0), afterY: (parseFloat(bordersWidth[borders.b]) || 0) + (parseFloat(paddingWidth[paddings.b]) || 0) }; }, getBorders: function() { var bordersWidth = this.getStyle(bordersTLRB); return { beforeX: (parseFloat(bordersWidth[borders.l]) || 0), afterX: (parseFloat(bordersWidth[borders.r]) || 0), beforeY: (parseFloat(bordersWidth[borders.t]) || 0), afterY: (parseFloat(bordersWidth[borders.b]) || 0) }; }, getBorderWidth: function(side) { return this.addStyles(side, borders); }, getData: function(preventCreate) { var dom = this.dom, data; if (dom) { data = dom._extData; if (!data && !preventCreate) { dom._extData = data = {}; } } return data; }, getFirstChild: function() { return Ext.get(this.dom.firstElementChild); }, getHeight: function(contentHeight, preciseHeight) { var me = this, hidden = me.isStyle('display', 'none'), height, floating; if (hidden) { return 0; } height = me.dom.offsetHeight; if (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"); } return (height < 0) ? 0 : height; }, getHtml: function() { return this.dom ? this.dom.innerHTML : ''; }, getLeft: function(local) { return local ? this.getLocalX() : this.getX(); }, getLocalX: function() { var me = this, offsetParent, x = me.getStyle('left'); if (!x || x === 'auto') { x = 0; } else if (pxRe.test(x)) { x = parseFloat(x); } else { x = me.getX(); offsetParent = me.dom.offsetParent; if (offsetParent) { x -= Ext.fly(offsetParent).getX(); } } return x; }, getLocalXY: function() { var me = this, offsetParent, style = me.getStyle([ 'left', 'top' ]), x = style.left, y = style.top; if (!x || x === 'auto') { x = 0; } else if (pxRe.test(x)) { x = parseFloat(x); } else { x = me.getX(); offsetParent = me.dom.offsetParent; if (offsetParent) { x -= Ext.fly(offsetParent).getX(); } } if (!y || y === 'auto') { y = 0; } else if (pxRe.test(y)) { y = parseFloat(y); } else { y = me.getY(); offsetParent = me.dom.offsetParent; if (offsetParent) { y -= Ext.fly(offsetParent).getY(); } } return [ x, y ]; }, getLocalY: function() { var me = this, offsetParent, y = me.getStyle('top'); if (!y || y === 'auto') { y = 0; } else if (pxRe.test(y)) { y = parseFloat(y); } else { y = me.getY(); offsetParent = me.dom.offsetParent; if (offsetParent) { y -= Ext.fly(offsetParent).getY(); } } return y; }, getMargin: (function() { var hash = { t: "top", l: "left", r: "right", b: "bottom" }, allMargins = [ 'margin-top', 'margin-left', 'margin-right', 'margin-bottom' ]; return function(side) { var me = this, style, key, o; if (!side) { style = me.getStyle(allMargins); o = {}; if (style && typeof style === 'object') { o = {}; for (key in margins) { o[key] = o[hash[key]] = parseFloat(style[margins[key]]) || 0; } } } else { o = me.addStyles(side, margins); } return o; }; })(), getPadding: function(side) { return this.addStyles(side, paddings); }, getParent: function() { return Ext.get(this.dom.parentNode); }, getRight: function(local) { return (local ? this.getLocalX() : this.getX()) + this.getWidth(); }, getScroll: function() { var me = this, dom = me.dom, docElement = DOC.documentElement, left, top, body = document.body; if (dom === DOC || dom === body) { left = docElement.scrollLeft || (body ? body.scrollLeft : 0); top = docElement.scrollTop || (body ? body.scrollTop : 0); } else { left = dom.scrollLeft; top = dom.scrollTop; } return { left: left, top: top }; }, getScrollIntoViewXY: function(container, scrollX, scrollY) { var dom = this.dom, ct = Ext.getDom(container), offsets = this.getOffsetsTo(ct), width = dom.offsetWidth, height = dom.offsetHeight, left = offsets[0] + scrollX, top = offsets[1] + scrollY, bottom = top + height, right = left + width, viewHeight = ct.clientHeight, viewWidth = ct.clientWidth, viewLeft = scrollX, viewTop = scrollY, viewBottom = viewTop + viewHeight, viewRight = viewLeft + viewWidth; if (height > viewHeight || top < viewTop) { scrollY = top; } else if (bottom > viewBottom) { scrollY = bottom - viewHeight; } if (width > viewWidth || left < viewLeft) { scrollX = left; } else if (right > viewRight) { scrollX = right - viewWidth; } return { x: scrollX, y: scrollY }; }, getScrollLeft: function() { var dom = this.dom; if (dom === DOC || dom === document.body) { return this.getScroll().left; } else { return dom.scrollLeft; } }, getScrollTop: function() { var dom = this.dom; if (dom === DOC || dom === document.body) { return this.getScroll().top; } else { return dom.scrollTop; } }, getSize: function(contentSize) { return { width: this.getWidth(contentSize), height: this.getHeight(contentSize) }; }, getStyle: function(property, inline) { var me = this, dom = me.dom, multiple = typeof property !== 'string', hooks = me.styleHooks, prop = property, props = prop, len = 1, domStyle, camel, values, hook, out, style, i; if (multiple) { values = {}; prop = props[0]; i = 0; if (!(len = props.length)) { return values; } } if (!dom || dom.documentElement) { return values || ''; } domStyle = dom.style; if (inline) { style = domStyle; } else { style = dom.ownerDocument.defaultView.getComputedStyle(dom, null); if (!style) { inline = true; style = domStyle; } } do { hook = hooks[prop]; if (!hook) { hooks[prop] = hook = { name: Element.normalize(prop) }; } if (hook.get) { out = hook.get(dom, me, inline, style); } else { camel = hook.name; out = style[camel]; } if (!multiple) { return out; } values[prop] = out; prop = props[++i]; } while (i < len); return values; }, getStyleValue: function(name) { return this.dom.style.getPropertyValue(name); }, getTop: function(local) { return local ? this.getLocalY() : this.getY(); }, getValue: function(asNumber) { var value = this.dom.value; return asNumber ? parseInt(value, 10) : value; }, getViewSize: function() { var dom = this.dom; if (dom === DOC || dom === DOC.body) { return { width: Element.getViewportWidth(), height: Element.getViewportHeight() }; } else { return { width: dom.clientWidth, height: dom.clientHeight }; } }, getVisibilityMode: function() { var me = this, data = me.getData(), mode = data.visibilityMode; if (mode === undefined) { data.visibilityMode = mode = Element.DISPLAY; } return mode; }, getWidth: function(contentWidth, preciseWidth) { var me = this, dom = me.dom, hidden = me.isStyle('display', 'none'), rect, width, floating; if (hidden) { return 0; } if (Ext.supports.BoundingClientRect) { rect = dom.getBoundingClientRect(); width = (me.vertical && !Ext.supports.RotatedBoundingClientRect) ? (rect.bottom - rect.top) : (rect.right - rect.left); width = preciseWidth ? width : Math.ceil(width); } else { width = dom.offsetWidth; } if (Ext.supports.Direct2DBug && !me.vertical) { 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"); } return (width < 0) ? 0 : width; }, getX: function() { return this.getXY()[0]; }, getXY: function() { var round = Math.round, dom = this.dom, x = 0, y = 0, box, scroll; if (dom !== DOC && dom !== DOC.body) { try { box = dom.getBoundingClientRect(); } catch (ex) { box = { left: 0, top: 0 }; } x = round(box.left); y = round(box.top); scroll = Ext.getDoc().getScroll(); x += scroll.left; y += scroll.top; } return [ x, y ]; }, getY: function() { return this.getXY()[1]; }, getZIndex: function() { return parseInt(this.getStyle('z-index'), 10); }, hasCls: function(name) { var elementData = this.getData(); if (!elementData.isSynchronized) { this.synchronize(); } return elementData.classMap.hasOwnProperty(name); }, hide: function() { this.setVisible(false); return this; }, insertAfter: function(el) { el = Ext.getDom(el); el.parentNode.insertBefore(this.dom, el.nextSibling); return this; }, insertBefore: function(el) { el = Ext.getDom(el); el.parentNode.insertBefore(this.dom, el); 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); } }, insertHtml: function(where, html, returnEl) { var el = Ext.DomHelper.insertHtml(where, this.dom, html); return returnEl ? Ext.get(el) : el; }, insertSibling: function(el, where, returnDom) { var me = this, DomHelper = Ext.DomHelper, isAfter = (where || 'before').toLowerCase() === 'after', rt, insertEl, eLen, e; if (Ext.isIterable(el)) { eLen = el.length; insertEl = Ext.fly(document.createDocumentFragment()); if (Ext.isArray(el)) { for (e = 0; e < eLen; e++) { rt = insertEl.appendChild(el[e], returnDom); } } else { for (e = 0; e < eLen; e++) { insertEl.dom.appendChild(rt = el[0]); } if (returnDom === false) { rt = Ext.get(rt); } } me.dom.parentNode.insertBefore(insertEl.dom, isAfter ? me.dom.nextSibling : me.dom); 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 = DomHelper.append(me.dom.parentNode, el, !returnDom); } else { rt = DomHelper[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom); } } return rt; }, is: function(selector) { var dom = this.dom, is; if (!selector) { is = true; } else if (!dom.tagName) { is = false; } else if (Ext.isFunction(selector)) { is = selector(dom); } else { is = dom[Ext.supports.matchesSelector](selector); } return is; }, isAncestor: function(el) { var ret = false, dom = this.dom, child = Ext.getDom(el); if (dom && child) { if (dom.contains) { return dom.contains(child); } else if (dom.compareDocumentPosition) { return !!(dom.compareDocumentPosition(child) & 16); } else { while ((child = child.parentNode)) { ret = child === dom || ret; } } } return ret; }, isPainted: (function() { return !Ext.browser.is.IE ? function() { var dom = this.dom; return Boolean(dom && dom.offsetParent); } : function() { var dom = this.dom; return Boolean(dom && (dom.offsetHeight !== 0 && dom.offsetWidth !== 0)); }; })(), isStyle: function(style, val) { return this.getStyle(style) === val; }, isVisible: function(deep) { var dom = this.dom, end; if (!dom) { return false; } if (!visFly) { visFly = new Ext.dom.Fly(); } for (end = dom.ownerDocument.documentElement; dom !== end; dom = dom.parentNode) { if (!dom || dom.nodeType === 11 || (visFly.attach(dom)).isStyle(VISIBILITY, HIDDEN) || visFly.isStyle(DISPLAY, NONE)) { return false; } if (!deep) { break; } } return true; }, last: function(selector, returnDom) { return this.matchNode('previousSibling', 'lastChild', selector, returnDom); }, matchNode: function(dir, start, selector, returnDom) { var dom = this.dom, n; if (!dom) { return null; } n = dom[start]; while (n) { if (n.nodeType === 1 && (!selector || Ext.fly(n, '_matchNode').is(selector))) { return !returnDom ? Ext.get(n) : n; } n = n[dir]; } return null; }, next: function(selector, returnDom) { return this.matchNode('nextSibling', 'nextSibling', selector, returnDom); }, parent: function(selector, returnDom) { return this.matchNode('parentNode', 'parentNode', selector, returnDom); }, position: function(pos, zIndex, x, y) { var me = this; if (me.dom.tagName !== 'BODY') { 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 ]); } } }, prev: function(selector, returnDom) { return this.matchNode('previousSibling', 'previousSibling', selector, returnDom); }, query: function(selector, asDom, single) { var dom = this.dom, results, len, nlen, node, nodes, i, j; if (!dom) { return null; } asDom = (asDom !== false); selector = selector.split(","); if (!single) { results = []; } for (i = 0 , len = selector.length; i < len; i++) { if (typeof selector[i] === 'string') { if (single) { node = dom.querySelector(selector[i]); return asDom ? node : Ext.get(node); } nodes = dom.querySelectorAll(selector[i]); for (j = 0 , nlen = nodes.length; j < nlen; j++) { results.push(asDom ? nodes[j] : Ext.get(nodes[j])); } } } return results; }, radioCls: function(className) { var cn = this.dom.parentNode.childNodes, v; className = Ext.isArray(className) ? className : [ className ]; for (var i = 0, len = cn.length; i < len; i++) { v = cn[i]; if (v && v.nodeType === 1) { Ext.fly(v).removeCls(className); } } return this.addCls(className); }, redraw: function() { var dom = this.dom, domStyle = dom.style; domStyle.display = 'none'; dom.offsetHeight; domStyle.display = ''; }, remove: function() { this.destroy(); }, removeChild: function(element) { this.dom.removeChild(Ext.getDom(element)); return this; }, removeCls: function(names, prefix, suffix) { var me = this, elementData = me.getData(), hasNewCls, dom, map, classList, i, ln, name; if (!names) { return me; } if (!elementData.isSynchronized) { me.synchronize(); } dom = me.dom; map = elementData.classMap; classList = elementData.classList; prefix = prefix ? prefix + SEPARATOR : ''; suffix = suffix ? SEPARATOR + suffix : ''; if (typeof names === 'string') { names = names.split(spacesRe); } for (i = 0 , ln = names.length; i < ln; i++) { name = names[i]; if (name) { name = prefix + name + suffix; if (map[name]) { delete map[name]; Ext.Array.remove(classList, name); hasNewCls = true; } } } if (hasNewCls) { dom.className = classList.join(' '); } return me; }, repaint: function() { var me = this; me.addCls(Ext.baseCSSPrefix + 'repaint'); Ext.defer(function() { if (me.dom) { Ext.fly(me.dom).removeCls(Ext.baseCSSPrefix + 'repaint'); } }, 1); return me; }, replace: function(el, destroy) { el = Ext.getDom(el); var parentNode = el.parentNode, id = el.id, dom = this.dom; if (!parentNode) { Ext.Error.raise('Cannot replace element "' + id + '". It is not attached to a parent node.'); } if (destroy !== false && id && Ext.cache[id]) { parentNode.insertBefore(dom, el); Ext.get(el).destroy(); } else { parentNode.replaceChild(dom, el); } return this; }, replaceCls: function(oldName, newName, prefix, suffix) { var me = this, dom, map, classList, i, ln, name, elementData = me.getData(); if (!oldName && !newName) { return me; } oldName = oldName || []; newName = newName || []; if (!elementData.isSynchronized) { me.synchronize(); } if (!suffix) { suffix = ''; } dom = me.dom; map = elementData.classMap; classList = elementData.classList; prefix = prefix ? prefix + SEPARATOR : ''; suffix = suffix ? SEPARATOR + suffix : ''; if (typeof oldName === 'string') { oldName = oldName.split(spacesRe); } if (typeof newName === 'string') { newName = newName.split(spacesRe); } for (i = 0 , ln = oldName.length; i < ln; i++) { name = prefix + oldName[i] + suffix; if (map[name]) { delete map[name]; Ext.Array.remove(classList, name); } } for (i = 0 , ln = newName.length; i < ln; i++) { name = prefix + newName[i] + suffix; if (!map[name]) { map[name] = true; classList.push(name); } } dom.className = classList.join(' '); return me; }, replaceWith: function(el) { var me = this, dom = me.dom, parent = dom.parentNode, cache = Ext.cache, newDom; me.clearListeners(); if (el.nodeType || el.dom || typeof el === 'string') { el = Ext.get(el); newDom = parent.insertBefore(el.dom, dom); } else { newDom = Ext.DomHelper.insertBefore(dom, el); } parent.removeChild(dom); me.dom = newDom; if (!me.isFly) { delete cache[me.id]; cache[me.id = Ext.id(newDom)] = me; } return me; }, resolveListenerScope: function(defaultScope) { var component = this.component; return component ? component.resolveListenerScope(defaultScope) : this; }, scroll: function(direction, distance, animate) { if (!this.isScrollable()) { return false; } direction = direction.charAt(0); var me = this, dom = me.dom, side = direction === 'r' || direction === 'l' ? 'left' : 'top', scrolled = false, currentScroll, constrainedScroll; if (direction === 'l' || direction === 't' || direction === 'u') { distance = -distance; } if (side === 'left') { currentScroll = dom.scrollLeft; constrainedScroll = me.constrainScrollLeft(currentScroll + distance); } else { currentScroll = dom.scrollTop; constrainedScroll = me.constrainScrollTop(currentScroll + distance); } if (constrainedScroll !== currentScroll) { this.scrollTo(side, constrainedScroll, animate); scrolled = true; } return scrolled; }, scrollBy: function(deltaX, deltaY, animate) { var me = this, dom = me.dom; if (deltaX.length) { animate = deltaY; deltaY = deltaX[1]; deltaX = deltaX[0]; } else if (typeof deltaX != 'number') { animate = deltaY; deltaY = deltaX.y; deltaX = deltaX.x; } if (deltaX) { me.scrollTo('left', me.constrainScrollLeft(dom.scrollLeft + deltaX), animate); } if (deltaY) { me.scrollTo('top', me.constrainScrollTop(dom.scrollTop + deltaY), animate); } return me; }, scrollChildIntoView: function(child, hscroll) { Ext.fly(child).scrollIntoView(this, hscroll); }, scrollIntoView: function(container, hscroll, animate, highlight) { container = Ext.getDom(container) || Ext.getBody().dom; return this.doScrollIntoView(container, hscroll, animate, highlight, 'getScrollLeft', 'scrollTo'); }, scrollTo: function(side, value, animate) { var top = topRe.test(side), me = this, prop = top ? 'scrollTop' : 'scrollLeft', dom = me.dom, animCfg; if (!animate || !me.anim) { dom[prop] = value; } else { animCfg = { to: {} }; animCfg.to[prop] = value; if (Ext.isObject(animate)) { Ext.applyIf(animCfg, animate); } me.animate(animCfg); } return me; }, select: function(selector, composite) { var isElementArray, elements; if (typeof selector === "string") { elements = this.query(selector, !composite); } else if (selector.length === undefined) { Ext.Error.raise("Invalid selector specified: " + selector); } else { elements = selector; isElementArray = true; } return composite ? new Ext.CompositeElement(elements, !isElementArray) : new Ext.CompositeElementLite(elements, true); }, selectNode: function(selector, asDom) { return this.query(selector, asDom, true); }, set: function(attributes, useSet) { var me = this, dom = me.dom, attribute, value; for (attribute in attributes) { if (attributes.hasOwnProperty(attribute)) { value = attributes[attribute]; if (attribute === 'style') { me.applyStyles(value); } else if (attribute === 'cls') { dom.className = value; } else if (useSet !== false) { if (value === undefined) { dom.removeAttribute(attribute); } else { dom.setAttribute(attribute, value); } } else { dom[attribute] = value; } } } return me; }, setBottom: function(bottom) { this.dom.style[BOTTOM] = Element.addUnits(bottom); return this; }, setBorder: function(border) { var me = this, domStyle = me.dom.style; if (border || border === 0) { border = me.self.unitizeBox((border === true) ? 1 : border); domStyle.setProperty('border-width', border, 'important'); } else { domStyle.removeProperty('border-top-width'); domStyle.removeProperty('border-right-width'); domStyle.removeProperty('border-bottom-width'); domStyle.removeProperty('border-left-width'); } }, setCls: function(className) { var me = this, elementData = me.getData(), i, ln, name, map; if (!elementData.isSynchronized) { me.synchronize(); } map = elementData.classMap; if (typeof className === 'string') { className = className.split(spacesRe); } for (i = 0 , ln = className.length; i < ln; i++) { name = className[i]; if (!map[name]) { map[name] = true; } } elementData.classList = className.slice(); me.dom.className = className.join(' '); }, setHeight: function(height) { var me = this; me.dom.style[HEIGHT] = Element.addUnits(height); if (me.shadow || me.shim) { me.syncUnderlays(); } return me; }, setHtml: function(html) { if (this.dom) { this.dom.innerHTML = html; } }, setId: function(id) { var me = this, currentId = me.id, cache = Ext.cache; if (currentId) { delete cache[currentId]; } me.dom.id = id; me.id = id; cache[id] = me; return me; }, setLeft: function(left) { var me = this; me.dom.style[LEFT] = Element.addUnits(left); if (me.shadow || me.shim) { me.syncUnderlays(); } return me; }, setLocalX: function(x) { var me = this, style = me.dom.style; style.right = 'auto'; style.left = (x === null) ? 'auto' : x + 'px'; if (me.shadow || me.shim) { me.syncUnderlays(); } return me; }, setLocalXY: function(x, y) { var me = this, style = me.dom.style; style.right = 'auto'; if (x && x.length) { y = x[1]; x = x[0]; } if (x === null) { style.left = 'auto'; } else if (x !== undefined) { style.left = x + 'px'; } if (y === null) { style.top = 'auto'; } else if (y !== undefined) { style.top = y + 'px'; } if (me.shadow || me.shim) { me.syncUnderlays(); } return me; }, setLocalY: function(y) { var me = this; me.dom.style.top = (y === null) ? 'auto' : y + 'px'; if (me.shadow || me.shim) { me.syncUnderlays(); } return me; }, setMargin: function(margin) { var me = this, domStyle = me.dom.style; if (margin || margin === 0) { margin = me.self.unitizeBox((margin === true) ? 5 : margin); domStyle.setProperty('margin', margin, 'important'); } else { domStyle.removeProperty('margin-top'); domStyle.removeProperty('margin-right'); domStyle.removeProperty('margin-bottom'); domStyle.removeProperty('margin-left'); } }, setMaxHeight: function(height) { this.dom.style[MAX_HEIGHT] = Element.addUnits(height); return this; }, setMaxWidth: function(width) { this.dom.style[MAX_WIDTH] = Element.addUnits(width); return this; }, setMinHeight: function(height) { this.dom.style[MIN_HEIGHT] = Element.addUnits(height); return this; }, setMinWidth: function(width) { this.dom.style[MIN_WIDTH] = Element.addUnits(width); return this; }, setPadding: function(padding) { var me = this, domStyle = me.dom.style; if (padding || padding === 0) { padding = me.self.unitizeBox((padding === true) ? 5 : padding); domStyle.setProperty('padding', padding, 'important'); } else { domStyle.removeProperty('padding-top'); domStyle.removeProperty('padding-right'); domStyle.removeProperty('padding-bottom'); domStyle.removeProperty('padding-left'); } }, setRight: function(right) { this.dom.style[RIGHT] = Element.addUnits(right); return this; }, setScrollLeft: function(left) { this.dom.scrollLeft = left; return this; }, setScrollTop: function(top) { this.dom.scrollTop = top; return this; }, setSize: function(width, height) { var me = this, style = me.dom.style; if (Ext.isObject(width)) { height = width.height; width = width.width; } style.width = Element.addUnits(width); style.height = Element.addUnits(height); if (me.shadow || me.shim) { me.syncUnderlays(); } return me; }, setSizeState: function(state) { var me = this, add, remove; if (state === true) { add = sizedCls; remove = [ unsizedCls, stretchedCls ]; } else if (state === false) { add = unsizedCls; remove = [ sizedCls, stretchedCls ]; } else if (state === null) { add = stretchedCls; remove = [ sizedCls, unsizedCls ]; } else { remove = [ sizedCls, unsizedCls, stretchedCls ]; } if (add) { me.addCls(add); } me.removeCls(remove); return me; }, setStyle: function(prop, value) { var me = this, dom = me.dom, hooks = me.styleHooks, style = dom.style, name = prop, hook; if (typeof name === 'string') { hook = hooks[name]; if (!hook) { hooks[name] = hook = { name: Element.normalize(name) }; } value = (value == null) ? '' : value; if (hook.set) { hook.set(dom, value, me); } else { style[hook.name] = value; } if (hook.afterSet) { hook.afterSet(dom, value, me); } } else { for (name in prop) { if (prop.hasOwnProperty(name)) { hook = hooks[name]; if (!hook) { hooks[name] = hook = { name: Element.normalize(name) }; } value = prop[name]; value = (value == null) ? '' : value; if (hook.set) { hook.set(dom, value, me); } else { style[hook.name] = value; } if (hook.afterSet) { hook.afterSet(dom, value, me); } } } } return me; }, setText: function(text) { this.dom.textContent = text; }, setTop: function(top) { var me = this; me.dom.style[TOP] = Element.addUnits(top); if (me.shadow || me.shim) { me.syncUnderlays(); } return me; }, setUnderlaysVisible: function(visible) { var shadow = this.shadow, shim = this.shim; if (shadow && !shadow.disabled) { if (visible) { shadow.show(); } else { shadow.hide(); } } if (shim && !shim.disabled) { if (visible) { shim.show(); } else { shim.hide(); } } }, setVisibility: function(isVisible) { var domStyle = this.dom.style; if (isVisible) { domStyle.removeProperty('visibility'); } else { domStyle.setProperty('visibility', 'hidden', 'important'); } }, setVisibilityMode: function(mode) { if (mode !== 1 && mode !== 2 && mode !== 3) { Ext.Error.raise("visibilityMode must be one of the following: " + "Ext.Element.DISPLAY, Ext.Element.VISIBILITY, or Ext.Element.OFFSETS"); } this.getData().visibilityMode = mode; return this; }, setVisible: function(visible) { var me = this, mode = me.getVisibilityMode(), method = visible ? 'removeCls' : 'addCls'; switch (mode) { case Element.DISPLAY: me.removeCls([ visibilityCls, offsetsCls ]); me[method](displayCls); break; case Element.VISIBILITY: me.removeCls([ displayCls, offsetsCls ]); me[method](visibilityCls); break; case Element.OFFSETS: me.removeCls([ visibilityCls, displayCls ]); me[method](offsetsCls); break; } if (me.shadow || me.shim) { me.setUnderlaysVisible(visible); } return me; }, setWidth: function(width) { var me = this; me.dom.style[WIDTH] = Element.addUnits(width); if (me.shadow || me.shim) { me.syncUnderlays(); } return me; }, setX: function(x) { return this.setXY([ x, false ]); }, setXY: function(xy) { var me = this, pts = me.translatePoints(xy), style = me.dom.style, pos; me.position(); style.right = 'auto'; for (pos in pts) { if (!isNaN(pts[pos])) { style[pos] = pts[pos] + 'px'; } } if (me.shadow || me.shim) { me.syncUnderlays(); } return me; }, setY: function(y) { return this.setXY([ false, y ]); }, setZIndex: function(zindex) { var me = this; if (me.shadow) { me.shadow.setZIndex(zindex); } if (me.shim) { me.shim.setZIndex(zindex); } return me.setStyle('z-index', zindex); }, show: function() { this.setVisible(true); return this; }, swapCls: function(firstClass, secondClass, flag, prefix) { if (flag === undefined) { flag = true; } var me = this, addedClass = flag ? firstClass : secondClass, removedClass = flag ? secondClass : firstClass; if (removedClass) { me.removeCls(prefix ? prefix + '-' + removedClass : removedClass); } if (addedClass) { me.addCls(prefix ? prefix + '-' + addedClass : addedClass); } return me; }, synchronize: function() { var me = this, dom = me.dom, hasClassMap = {}, className = dom.className, classList, i, ln, name, elementData = me.getData(); if (className && className.length > 0) { classList = dom.className.split(classNameSplitRegex); for (i = 0 , ln = classList.length; i < ln; i++) { name = classList[i]; hasClassMap[name] = true; } } else { classList = []; } elementData.classList = classList; elementData.classMap = hasClassMap; elementData.isSynchronized = true; return me; }, syncUnderlays: function() { var me = this, shadow = me.shadow, shim = me.shim, dom = me.dom, xy, x, y, w, h; if (me.isVisible()) { xy = me.getXY(); x = xy[0]; y = xy[1]; w = dom.offsetWidth; h = dom.offsetHeight; if (shadow && !shadow.hidden) { shadow.realign(x, y, w, h); } if (shim && !shim.hidden) { shim.realign(x, y, w, h); } } }, toggleCls: function(className, force) { if (typeof force !== 'boolean') { force = !this.hasCls(className); } return (force) ? this.addCls(className) : this.removeCls(className); }, toggle: function() { this.setVisible(!this.isVisible()); return this; }, translate: function() { var transformStyleName = 'webkitTransform' in DOC.createElement('div').style ? 'webkitTransform' : 'transform'; return function(x, y, z) { this.dom.style[transformStyleName] = 'translate3d(' + (x || 0) + 'px, ' + (y || 0) + 'px, ' + (z || 0) + 'px)'; }; }(), unwrap: function() { var dom = this.dom, parentNode = dom.parentNode, grandparentNode, activeElement = Ext.fly(Ext.Element.getActiveElement()), resumeFocus; if (this.contains(activeElement)) { Ext.GlobalEvents.suspendEvent('focus'); activeElement.suspendEvent('focus', 'blur'); resumeFocus = true; } if (parentNode) { grandparentNode = parentNode.parentNode; grandparentNode.insertBefore(dom, parentNode); grandparentNode.removeChild(parentNode); } else { grandparentNode = document.createDocumentFragment(); grandparentNode.appendChild(dom); } if (resumeFocus) { activeElement.focus(); Ext.GlobalEvents.resumeEvent('focus'); activeElement.resumeEvent('focus', 'blur'); } return this; }, up: function(simpleSelector, limit, returnDom) { return this.findParentNode(simpleSelector, limit, !returnDom); }, update: function(html) { return this.setHtml(html); }, wrap: function(config, returnDom, selector) { var me = this, dom = me.dom, newEl = Ext.DomHelper.insertBefore(dom, config || { tag: "div" }, !returnDom), target = newEl, activeElement = Ext.fly(Ext.Element.getActiveElement()), resumeFocus; if (selector) { target = newEl.selectNode(selector, returnDom); } if (me.contains(activeElement)) { Ext.GlobalEvents.suspendEvent('focus'); activeElement.suspendEvent('focus', 'blur'); resumeFocus = true; } target.appendChild(dom); if (resumeFocus) { activeElement.focus(); activeElement.resumeEvent('focus', 'blur'); Ext.GlobalEvents.resumeEvent('focus'); } return newEl; }, privates: { doAddListener: function(eventName, fn, scope, options, order, caller, manager) { var me = this, observableDoAddListener, additiveEventName, translatedEventName; eventName = Ext.canonicalEventName(eventName); if (!me.blockedEvents[eventName]) { observableDoAddListener = me.mixins.observable.doAddListener; options = options || {}; if (me.longpressEvents[eventName]) { me.disableTouchContextMenu(); } if (Element.useDelegatedEvents === false) { options.delegated = options.delegated || false; } if (options.translate !== false) { additiveEventName = me.additiveEvents[eventName]; if (additiveEventName) { options.type = eventName; eventName = additiveEventName; observableDoAddListener.call(me, eventName, fn, scope, options, order, caller, manager); } translatedEventName = me.eventMap[eventName]; if (translatedEventName) { options.type = options.type || eventName; eventName = translatedEventName; } } observableDoAddListener.call(me, eventName, fn, scope, options, order, caller, manager); delete options.type; } }, doRemoveListener: function(eventName, fn, scope) { var me = this, observableDoRemoveListener, translatedEventName, additiveEventName, contextMenuListenerRemover; if (!me.blockedEvents[eventName]) { observableDoRemoveListener = me.mixins.observable.doRemoveListener; if (me.longpressEvents[eventName]) { contextMenuListenerRemover = this._contextMenuListenerRemover; if (contextMenuListenerRemover) { contextMenuListenerRemover.destroy(); } } additiveEventName = me.additiveEvents[eventName]; if (additiveEventName) { eventName = additiveEventName; observableDoRemoveListener.call(me, eventName, fn, scope); } translatedEventName = me.eventMap[eventName]; if (translatedEventName) { observableDoRemoveListener.call(me, translatedEventName, fn, scope); } observableDoRemoveListener.call(me, eventName, fn, scope); } }, _initEvent: function(eventName) { return (this.events[eventName] = new Ext.dom.ElementEvent(this, eventName)); }, _getPublisher: function(eventName) { var Publisher = Ext.event.publisher.Publisher, publisher = Publisher.publishersByEvent[eventName]; if (!publisher || (this.dom === window && eventName === 'resize')) { publisher = Publisher.publishers.dom; } return publisher; } }, deprecated: { '5.0': { methods: { cssTranslate: null, getHTML: 'getHtml', getOuterHeight: null, getOuterWidth: null, getPageBox: function(getRegion) { var me = this, dom = me.dom, isDoc = dom.nodeName === 'BODY', w = isDoc ? Element.getViewportWidth() : dom.offsetWidth, h = isDoc ? Element.getViewportHeight() : dom.offsetHeight, xy = me.getXY(), t = xy[1], r = xy[0] + w, b = xy[1] + h, l = xy[0]; if (getRegion) { return new Ext.util.Region(t, r, b, l); } else { return { left: l, top: t, width: w, height: h, right: r, bottom: b }; } }, getScrollParent: null, isDescendent: null, isTransparent: function(prop) { var value = this.getStyle(prop); return value ? transparentRe.test(value) : false; }, purgeAllListeners: 'clearListeners', removeAllListeners: 'clearListeners', setHTML: 'setHtml', setTopLeft: null } } } }; }, function(Element) { var DOC = document, prototype = Element.prototype, supports = Ext.supports, pointerdown = 'pointerdown', pointermove = 'pointermove', pointerup = 'pointerup', pointercancel = 'pointercancel', MSPointerDown = 'MSPointerDown', MSPointerMove = 'MSPointerMove', MSPointerUp = 'MSPointerUp', MSPointerCancel = 'MSPointerCancel', mousedown = 'mousedown', mousemove = 'mousemove', mouseup = 'mouseup', mouseover = 'mouseover', mouseout = 'mouseout', mouseenter = 'mouseenter', mouseleave = 'mouseleave', touchstart = 'touchstart', touchmove = 'touchmove', touchend = 'touchend', touchcancel = 'touchcancel', click = 'click', dblclick = 'dblclick', tap = 'tap', doubletap = 'doubletap', eventMap = prototype.eventMap = {}, additiveEvents = prototype.additiveEvents = {}, oldId = Ext.id, eventOptions; Ext.id = function(obj, prefix) { var el = Ext.getDom(obj, true), sandboxPrefix, id; if (!el) { id = oldId(obj, prefix); } else if (!(id = el.id)) { id = oldId(null, prefix || Element.prototype.identifiablePrefix); if (Ext.isSandboxed) { sandboxPrefix = Ext.sandboxPrefix || (Ext.sandboxPrefix = Ext.sandboxName.toLowerCase() + '-'); id = sandboxPrefix + id; } el.id = id; } return id; }; if (supports.PointerEvents) { eventMap[mousedown] = pointerdown; eventMap[mousemove] = pointermove; eventMap[mouseup] = pointerup; eventMap[touchstart] = pointerdown; eventMap[touchmove] = pointermove; eventMap[touchend] = pointerup; eventMap[touchcancel] = pointercancel; eventMap[click] = tap; eventMap[dblclick] = doubletap; eventMap[mouseover] = 'pointerover'; eventMap[mouseout] = 'pointerout'; eventMap[mouseenter] = 'pointerenter'; eventMap[mouseleave] = 'pointerleave'; } else if (supports.MSPointerEvents) { eventMap[pointerdown] = MSPointerDown; eventMap[pointermove] = MSPointerMove; eventMap[pointerup] = MSPointerUp; eventMap[pointercancel] = MSPointerCancel; eventMap[mousedown] = MSPointerDown; eventMap[mousemove] = MSPointerMove; eventMap[mouseup] = MSPointerUp; eventMap[touchstart] = MSPointerDown; eventMap[touchmove] = MSPointerMove; eventMap[touchend] = MSPointerUp; eventMap[touchcancel] = MSPointerCancel; eventMap[click] = tap; eventMap[dblclick] = doubletap; eventMap[mouseover] = 'MSPointerOver'; eventMap[mouseout] = 'MSPointerOut'; } else if (supports.TouchEvents) { eventMap[pointerdown] = touchstart; eventMap[pointermove] = touchmove; eventMap[pointerup] = touchend; eventMap[pointercancel] = touchcancel; eventMap[mousedown] = touchstart; eventMap[mousemove] = touchmove; eventMap[mouseup] = touchend; eventMap[click] = tap; eventMap[dblclick] = doubletap; if (Ext.isWebKit && Ext.os.is.Desktop) { eventMap[touchstart] = mousedown; eventMap[touchmove] = mousemove; eventMap[touchend] = mouseup; eventMap[touchcancel] = mouseup; additiveEvents[mousedown] = mousedown; additiveEvents[mousemove] = mousemove; additiveEvents[mouseup] = mouseup; additiveEvents[touchstart] = touchstart; additiveEvents[touchmove] = touchmove; additiveEvents[touchend] = touchend; additiveEvents[touchcancel] = touchcancel; additiveEvents[pointerdown] = mousedown; additiveEvents[pointermove] = mousemove; additiveEvents[pointerup] = mouseup; additiveEvents[pointercancel] = mouseup; } } else { eventMap[pointerdown] = mousedown; eventMap[pointermove] = mousemove; eventMap[pointerup] = mouseup; eventMap[pointercancel] = mouseup; eventMap[touchstart] = mousedown; eventMap[touchmove] = mousemove; eventMap[touchend] = mouseup; eventMap[touchcancel] = mouseup; } if (Ext.isWebKit) { eventMap.transitionend = Ext.browser.getVendorProperyName('transitionEnd'); eventMap.animationstart = Ext.browser.getVendorProperyName('animationStart'); eventMap.animationend = Ext.browser.getVendorProperyName('animationEnd'); } if (!Ext.supports.MouseWheel && !Ext.isOpera) { eventMap.mousewheel = 'DOMMouseScroll'; } eventOptions = prototype.$eventOptions = Ext.Object.chain(prototype.$eventOptions); eventOptions.translate = eventOptions.capture = eventOptions.delegate = eventOptions.delegated = eventOptions.stopEvent = eventOptions.preventDefault = eventOptions.stopPropagation = eventOptions.element = 1; prototype.getTrueXY = prototype.getXY; Ext.select = Element.select; Ext.query = Element.query; Ext.apply(Ext, { get: function(element) { return Element.get(element); }, getDom: function(el) { if (!el || !DOC) { return null; } return el.dom || (typeof el === 'string' ? Ext.getElementById(el) : el); }, getBody: function() { if (!Ext._bodyEl) { if (!DOC.body) { throw new Error("[Ext.getBody] document.body does not yet exist"); } Ext._bodyEl = Ext.get(DOC.body); } return Ext._bodyEl; }, getHead: function() { if (!Ext._headEl) { Ext._headEl = Ext.get(DOC.head || DOC.getElementsByTagName('head')[0]); } return Ext._headEl; }, getDoc: function() { if (!Ext._docEl) { Ext._docEl = Ext.get(DOC); } return Ext._docEl; }, getWin: function() { if (!Ext._winEl) { Ext._winEl = Ext.get(window); } return Ext._winEl; }, removeNode: function(node) { node = node.dom || node; var id = node && node.id, el = Ext.cache[id], parent; if (el) { el.destroy(); } else if (node && (node.nodeType === 3 || node.tagName.toUpperCase() !== 'BODY')) { parent = node.parentNode; if (parent) { parent.removeChild(node); } } } }); Ext.isGarbage = function(dom) { return dom && dom.nodeType === 1 && dom.tagName !== 'BODY' && dom.tagName !== 'HTML' && (!dom.parentNode || (!dom.offsetParent && ((Ext.isIE8 ? DOC.all[dom.id] : DOC.getElementById(dom.id)) !== dom) && !(Ext.detachedBodyEl && Ext.detachedBodyEl.isAncestor(dom)))); }; }); Ext.define('Ext.util.Filter', { isFilter: true, config: { property: null, value: null, filterFn: null, id: null, anyMatch: false, exactMatch: false, caseSensitive: false, disabled: false, disableOnEmpty: false, operator: null, root: null, serializer: null, convert: null }, scope: null, $configStrict: false, statics: { createFilterFn: function(filters) { if (!filters) { return Ext.returnTrue; } return function(candidate) { var items = filters.isCollection ? filters.items : filters, length = items.length, match = true, i, filter; for (i = 0; match && i < length; i++) { filter = items[i]; if (!filter.getDisabled()) { match = filter.filter(candidate); } } return match; }; }, isInvalid: function(cfg) { if (!cfg.filterFn) { if (!cfg.property) { return 'A Filter requires either a property or a filterFn to be set'; } if (!cfg.hasOwnProperty('value') && !cfg.operator) { return 'A Filter requires either a property and value, or a filterFn to be set'; } } return false; } }, constructor: function(config) { var warn = Ext.util.Filter.isInvalid(config); if (warn) { Ext.log.warn(warn); } this.initConfig(config); }, preventConvert: { 'in': 1 }, filter: function(item) { var me = this, filterFn = me._filterFn || me.getFilterFn(), convert = me.getConvert(), value = me._value; me._filterValue = value; me.isDateValue = Ext.isDate(value); if (me.isDateValue) { me.dateValue = value.getTime(); } if (convert && !me.preventConvert[me.getOperator()]) { me._filterValue = convert.call(me.scope || me, value); } return filterFn.call(me.scope || me, item); }, getId: function() { var id = this._id; if (!id) { id = this.getProperty(); if (!id) { id = Ext.id(null, 'ext-filter-'); } this._id = id; } return id; }, getFilterFn: function() { var me = this, filterFn = me._filterFn, operator; if (!filterFn) { operator = me.getOperator(); if (operator) { filterFn = me.operatorFns[operator]; } else { filterFn = me.createRegexFilter(); } me._filterFn = filterFn; } return filterFn; }, createRegexFilter: function() { var me = this, anyMatch = !!me.getAnyMatch(), exact = !!me.getExactMatch(), value = me.getValue(), matcher = Ext.String.createRegex(value, !anyMatch, !anyMatch && exact, !me.getCaseSensitive()); return function(item) { var val = me.getPropertyValue(item); return matcher ? matcher.test(val) : (val == null); }; }, getPropertyValue: function(item) { var root = this._root, value = (root == null) ? item : item[root]; return value[this._property]; }, getState: function() { var config = this.getInitialConfig(), result = {}, name; for (name in config) { if (config.hasOwnProperty(name)) { result[name] = config[name]; } } delete result.root; result.value = this.getValue(); return result; }, getScope: function() { return this.scope; }, serialize: function() { var result = this.getState(), serializer = this.getSerializer(); delete result.id; delete result.serializer; if (serializer) { serializer.call(this, result); } return result; }, updateOperator: function() { this._filterFn = null; }, updateValue: function(value) { this._filterFn = null; if (this.getDisableOnEmpty()) { this.setDisabled(Ext.isEmpty(value)); } }, updateDisableOnEmpty: function(disableOnEmpty) { var disabled = false; if (disableOnEmpty) { disabled = Ext.isEmpty(this.getValue()); } this.setDisabled(disabled); }, privates: { getCandidateValue: function(candidate, v, preventCoerce) { var me = this, convert = me._convert, result = me.getPropertyValue(candidate); if (convert) { result = convert.call(me.scope || me, result); } else if (!preventCoerce) { result = Ext.coerce(result, v); } return result; } } }, function() { var prototype = this.prototype, operatorFns = (prototype.operatorFns = { "<": function(candidate) { var v = this._filterValue; return this.getCandidateValue(candidate, v) < v; }, "<=": function(candidate) { var v = this._filterValue; return this.getCandidateValue(candidate, v) <= v; }, "=": function(candidate) { var me = this, v = me._filterValue; candidate = me.getCandidateValue(candidate, v); if (me.isDateValue && candidate instanceof Date) { candidate = candidate.getTime(); v = me.dateValue; } return candidate == v; }, "===": function(candidate) { var me = this, v = me._filterValue; candidate = me.getCandidateValue(candidate, v, true); if (me.isDateValue && candidate instanceof Date) { candidate = candidate.getTime(); v = me.dateValue; } return candidate === v; }, ">=": function(candidate) { var v = this._filterValue; return this.getCandidateValue(candidate, v) >= v; }, ">": function(candidate) { var v = this._filterValue; return this.getCandidateValue(candidate, v) > v; }, "!=": function(candidate) { var me = this, v = me._filterValue; candidate = me.getCandidateValue(candidate, v); if (me.isDateValue && candidate instanceof Date) { candidate = candidate.getTime(); v = me.dateValue; } return candidate != v; }, "!==": function(candidate) { var me = this, v = me._filterValue; candidate = me.getCandidateValue(candidate, v, true); if (me.isDateValue && candidate instanceof Date) { candidate = candidate.getTime(); v = me.dateValue; } return candidate !== v; }, "in": function(candidate) { var v = this._filterValue; return Ext.Array.contains(v, this.getCandidateValue(candidate, v)); }, like: function(candidate) { var v = this._filterValue; return v && this.getCandidateValue(candidate, v).toLowerCase().indexOf(v.toLowerCase()) > -1; } }); operatorFns['=='] = operatorFns['=']; operatorFns.gt = operatorFns['>']; operatorFns.ge = operatorFns['>=']; operatorFns.lt = operatorFns['<']; operatorFns.le = operatorFns['<=']; operatorFns.eq = operatorFns['=']; operatorFns.ne = operatorFns['!=']; }); Ext.define('Ext.util.Observable', { extend: 'Ext.mixin.Observable', $applyConfigs: true }, function(Observable) { var Super = Ext.mixin.Observable; Observable.releaseCapture = Super.releaseCapture; Observable.capture = Super.capture; Observable.captureArgs = Super.captureArgs; Observable.observe = Observable.observeClass = Super.observe; }); Ext.define('Ext.util.AbstractMixedCollection', { requires: [ 'Ext.util.Filter' ], mixins: { observable: 'Ext.util.Observable' }, isMixedCollection: true, generation: 0, indexGeneration: 0, constructor: function(allowFunctions, keyFn) { var me = this; if (arguments.length === 1 && Ext.isObject(allowFunctions)) { me.initialConfig = allowFunctions; Ext.apply(me, allowFunctions); } else { me.allowFunctions = allowFunctions === true; if (keyFn) { me.getKey = keyFn; } me.initialConfig = { allowFunctions: me.allowFunctions, getKey: me.getKey }; } me.items = []; me.map = {}; me.keys = []; me.indexMap = {}; me.length = 0; me.mixins.observable.constructor.call(me); }, allowFunctions: false, add: function(key, obj) { var len = this.length, out; if (arguments.length === 1) { out = this.insert(len, key); } else { out = this.insert(len, key, obj); } return out; }, 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); } me.generation++; index = me.indexOfKey(key); me.items[index] = o; me.map[key] = o; if (me.hasListeners.replace) { me.fireEvent('replace', key, old, o); } return o; }, updateKey: function(oldKey, newKey) { var me = this, map = me.map, index = me.indexOfKey(oldKey), indexMap = me.indexMap, item; if (index > -1) { item = map[oldKey]; delete map[oldKey]; delete indexMap[oldKey]; map[newKey] = item; indexMap[newKey] = index; me.keys[index] = newKey; me.indexGeneration = ++me.generation; } }, addAll: function(objs) { var me = this, key; if (arguments.length > 1 || Ext.isArray(objs)) { me.insert(me.length, arguments.length > 1 ? arguments : objs); } 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 = Ext.Array.push([], 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 out; if (Ext.isIterable(key)) { out = this.doInsert(index, key, obj); } else { if (arguments.length > 2) { out = this.doInsert(index, [ key ], [ obj ]); } else { out = this.doInsert(index, [ key ]); } out = out[0]; } return out; }, doInsert: function(index, keys, objects) { var me = this, itemKey, removeIndex, i, len = keys.length, deDupedLen = len, fireAdd = me.hasListeners.add, syncIndices, newKeys = {}, passedDuplicates, oldKeys, oldObjects; if (objects != null) { me.useLinearSearch = true; } else { objects = keys; keys = new Array(len); for (i = 0; i < len; i++) { keys[i] = this.getKey(objects[i]); } } me.suspendEvents(); for (i = 0; i < len; i++) { itemKey = keys[i]; removeIndex = me.indexOfKey(itemKey); if (removeIndex !== -1) { if (removeIndex < index) { index--; } me.removeAt(removeIndex); } if (itemKey != null) { if (newKeys[itemKey] != null) { passedDuplicates = true; deDupedLen--; } newKeys[itemKey] = i; } } me.resumeEvents(); if (passedDuplicates) { oldKeys = keys; oldObjects = objects; keys = new Array(deDupedLen); objects = new Array(deDupedLen); i = 0; for (itemKey in newKeys) { keys[i] = oldKeys[newKeys[itemKey]]; objects[i] = oldObjects[newKeys[itemKey]]; i++; } len = deDupedLen; } syncIndices = index === me.length && me.indexGeneration === me.generation; Ext.Array.insert(me.items, index, objects); Ext.Array.insert(me.keys, index, keys); me.length += len; me.generation++; if (syncIndices) { me.indexGeneration = me.generation; } for (i = 0; i < len; i++ , index++) { itemKey = keys[i]; if (itemKey != null) { me.map[itemKey] = objects[i]; if (syncIndices) { me.indexMap[itemKey] = index; } } if (fireAdd) { me.fireEvent('add', index, objects[i], itemKey); } } return objects; }, remove: function(o) { var me = this, removeKey, index; if (!me.useLinearSearch && (removeKey = me.getKey(o))) { index = me.indexOfKey(removeKey); } else { index = Ext.Array.indexOf(me.items, o); } return (index === -1) ? false : me.removeAt(index); }, removeAll: function(items) { var me = this, i; if (items || me.hasListeners.remove) { if (items) { for (i = items.length - 1; i >= 0; --i) { me.remove(items[i]); } } else { while (me.length) { me.removeAt(0); } } } else { me.length = me.items.length = me.keys.length = 0; me.map = {}; me.indexMap = {}; me.generation++; me.indexGeneration = me.generation; } }, removeAt: function(index) { var me = this, o, key; if (index < me.length && index >= 0) { me.length--; o = me.items[index]; Ext.Array.erase(me.items, index, 1); key = me.keys[index]; if (typeof key != 'undefined') { delete me.map[key]; } Ext.Array.erase(me.keys, index, 1); if (me.hasListeners.remove) { me.fireEvent('remove', o, key); } me.generation++; return o; } return false; }, removeRange: function(index, removeCount) { var me = this, o, key, i, limit, syncIndices, trimming; if (index < me.length && index >= 0) { if (!removeCount) { removeCount = 1; } limit = Math.min(index + removeCount, me.length); removeCount = limit - index; trimming = limit === me.length; syncIndices = trimming && me.indexGeneration === me.generation; for (i = index; i < limit; i++) { key = me.keys[i]; if (key != null) { delete me.map[key]; if (syncIndices) { delete me.indexMap[key]; } } } o = me.items[i - 1]; me.length -= removeCount; me.generation++; if (syncIndices) { me.indexGeneration = me.generation; } if (trimming) { me.items.length = me.keys.length = me.length; } else { me.items.splice(index, removeCount); me.keys.splice(index, removeCount); } return o; } return false; }, removeAtKey: function(key) { var me = this, keys = me.keys, i; if (key == null) { for (i = keys.length - 1; i >= 0; i--) { if (keys[i] == null) { me.removeAt(i); } } } else { return me.removeAt(me.indexOfKey(key)); } }, getCount: function() { return this.length; }, indexOf: function(o) { var me = this, key; if (o != null) { if (!me.useLinearSearch && (key = me.getKey(o))) { return this.indexOfKey(key); } return Ext.Array.indexOf(me.items, o); } return -1; }, indexOfKey: function(key) { if (!this.map.hasOwnProperty(key)) { return -1; } if (this.indexGeneration !== this.generation) { this.rebuildIndexMap(); } return this.indexMap[key]; }, rebuildIndexMap: function() { var me = this, indexMap = me.indexMap = {}, keys = me.keys, len = keys.length, i; for (i = 0; i < len; i++) { indexMap[keys[i]] = i; } me.indexGeneration = me.generation; }, 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) { var me = this, key; if (o != null) { if (!me.useLinearSearch && (key = me.getKey(o))) { return this.map[key] != null; } return Ext.Array.indexOf(this.items, o) !== -1; } return false; }, containsKey: function(key) { return this.map.hasOwnProperty(key); }, clear: function() { var me = this; if (me.generation) { me.length = 0; me.items = []; me.keys = []; me.map = {}; me.indexMap = {}; me.generation++; me.indexGeneration = me.generation; } if (me.hasListeners.clear) { 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); }, hasRange: function(start, end) { return (end < this.length); }, getRange: function(start, end) { var me = this, items = me.items, range = [], len = items.length, tmp, reverse; if (len < 1) { return range; } if (start > end) { reverse = true; tmp = start; start = end; end = tmp; } if (start < 0) { start = 0; } if (end == null || end >= len) { end = len - 1; } range = items.slice(start, end + 1); if (reverse && range.length) { range.reverse(); } return range; }, filter: function(property, value, anyMatch, caseSensitive) { var filters = []; if (Ext.isString(property)) { filters.push(new 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); } return this.filterBy(Ext.util.Filter.createFilterFn(filters)); }, filterBy: function(fn, scope) { var me = this, newMC = new me.self(me.initialConfig), 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]); } } newMC.useLinearSearch = me.useLinearSearch; 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 me.self(me.initialConfig); copy.add(me.keys, me.items); copy.useLinearSearch = me.useLinearSearch; return copy; } }); Ext.define('Ext.util.Sorter', { isSorter: true, config: { property: null, sorterFn: null, root: null, transform: null, direction: "ASC", id: undefined }, statics: { createComparator: function(sorters, nextFn) { nextFn = nextFn || 0; return function(lhs, rhs) { var items = sorters.isCollection ? sorters.items : sorters, n = items.length, comp, i; for (i = 0; i < n; ++i) { comp = items[i].sort(lhs, rhs); if (comp) { return comp; } } return nextFn && nextFn(lhs, rhs); }; } }, multiplier: 1, constructor: function(config) { if (config && !this.isGrouper) { if (!config.property === !config.sorterFn) { Ext.Error.raise("A Sorter requires either a property or a sorterFn."); } } this.initConfig(config); }, getId: function() { var id = this._id; if (!id) { id = this.getProperty(); if (!id) { id = Ext.id(null, 'ext-sorter-'); } this._id = id; } return id; }, sort: function(lhs, rhs) { return this.multiplier * this.sortFn(lhs, rhs); }, sortFn: function(item1, item2) { var me = this, transform = me._transform, root = me._root, property = me._property, lhs, rhs; if (root) { item1 = item1[root]; item2 = item2[root]; } lhs = item1[property]; rhs = item2[property]; if (transform) { lhs = transform(lhs); rhs = transform(rhs); } return (lhs > rhs) ? 1 : (lhs < rhs ? -1 : 0); }, applyDirection: function(direction) { return direction ? direction : 'ASC'; }, updateDirection: function(direction) { this.multiplier = (direction.toUpperCase() === "DESC") ? -1 : 1; }, updateProperty: function(property) { if (property) { delete this.sortFn; } }, updateSorterFn: function(sorterFn) { this.sortFn = sorterFn; }, toggle: function() { this.setDirection(Ext.String.toggle(this.getDirection(), "ASC", "DESC")); }, getState: function() { return { root: this.getRoot(), property: this.getProperty(), direction: this.getDirection() }; }, serialize: function() { return { property: this.getProperty(), direction: this.getDirection() }; } }); Ext.define("Ext.util.Sortable", { isSortable: true, $configPrefixed: false, $configStrict: false, config: { sorters: null }, defaultSortDirection: "ASC", requires: [ 'Ext.util.Sorter' ], multiSortLimit: 3, statics: { createComparator: function(sorters) { return sorters && sorters.length ? function(r1, r2) { var result = sorters[0].sort(r1, r2), length = sorters.length, i = 1; for (; !result && i < length; i++) { result = sorters[i].sort.call(this, r1, r2); } return result; } : function() { return 0; }; } }, applySorters: function(sorters) { var me = this, sortersCollection = me.getSorters() || new Ext.util.MixedCollection(false, Ext.returnId); if (sorters) { sortersCollection.addAll(me.decodeSorters(sorters)); } return sortersCollection; }, sort: function(sorters, direction, insertionPosition, doSort) { var me = this, sorter, overFlow, currentSorters = me.getSorters(); if (!currentSorters) { me.setSorters(null); currentSorters = me.getSorters(); } if (Ext.isArray(sorters)) { doSort = insertionPosition; insertionPosition = direction; } else if (Ext.isObject(sorters)) { sorters = [ sorters ]; doSort = insertionPosition; insertionPosition = direction; } else if (Ext.isString(sorters)) { sorter = currentSorters.get(sorters); if (!sorter) { sorter = { property: sorters, direction: direction }; } else if (direction == null) { sorter.toggle(); } else { sorter.setDirection(direction); } sorters = [ sorter ]; } if (sorters && sorters.length) { sorters = me.decodeSorters(sorters); switch (insertionPosition) { case "multi": currentSorters.insert(0, sorters[0]); overFlow = currentSorters.getCount() - me.multiSortLimit; if (overFlow > 0) { currentSorters.removeRange(me.multiSortLimit, overFlow); }; break; case "prepend": currentSorters.insert(0, sorters); break; case "append": currentSorters.addAll(sorters); break; case undefined: case null: case "replace": currentSorters.clear(); currentSorters.addAll(sorters); break; default: Ext.Error.raise('Sorter insertion point must be "multi", "prepend", "append" or "replace"'); } } if (doSort !== false) { me.fireEvent('beforesort', me, sorters); me.onBeforeSort(sorters); if (me.getSorterCount()) { me.doSort(me.generateComparator()); } } return sorters; }, getSorterCount: function() { return this.getSorters().items.length; }, generateComparator: function() { var sorters = this.getSorters().getRange(); return sorters.length ? this.createComparator(sorters) : this.emptyComparator; }, emptyComparator: function() { return 0; }, 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, model = this.getModel ? this.getModel() : this.model, 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 (model && !config.transform) { field = model.getField(config.property); config.transform = field && field.sortType !== Ext.identityFn ? field.sortType : undefined; } sorters[i] = new Ext.util.Sorter(config); } } return sorters; }, getFirstSorter: function() { var sorters = this.getSorters().items, len = sorters.length, i = 0, sorter; for (; i < len; ++i) { sorter = sorters[i]; if (!sorter.isGrouper) { return sorter; } } return null; } }, function() { this.prototype.createComparator = this.createComparator; }); Ext.define('Ext.util.MixedCollection', { extend: 'Ext.util.AbstractMixedCollection', mixins: { sortable: 'Ext.util.Sortable' }, constructor: function() { this.initConfig(); this.callParent(arguments); }, 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, o; 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) { return fn(a[property], b[property]) * dsc || (a.index < b.index ? -1 : 1); }); for (i = 0 , len = c.length; i < len; i++) { o = c[i]; items[i] = o.value; keys[i] = o.key; me.indexMap[o.key] = i; } me.generation++; me.indexGeneration = me.generation; me.fireEvent('sort', me); }, sortBy: function(sorterFn) { var me = this, items = me.items, item, keys = me.keys, key, length = items.length, i; for (i = 0; i < length; i++) { items[i].$extCollectionIndex = i; } Ext.Array.sort(items, function(a, b) { return sorterFn(a, b) || (a.$extCollectionIndex < b.$extCollectionIndex ? -1 : 1); }); for (i = 0; i < length; i++) { item = items[i]; key = me.getKey(item); keys[i] = key; me.indexMap[key] = i; delete items.$extCollectionIndex; } me.generation++; me.indexGeneration = me.generation; me.fireEvent('sort', me, items, keys); }, findInsertionIndex: function(newItem, sorterFn) { var me = this, items = me.items, start = 0, end = items.length - 1, middle, comparison; if (!sorterFn) { sorterFn = me.generateComparator(); } while (start <= end) { middle = (start + end) >> 1; comparison = sorterFn(newItem, items[middle]); if (comparison >= 0) { start = middle + 1; } else if (comparison < 0) { end = middle - 1; } } return start; }, 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.util.TaskRunner', { interval: 10, timerId: null, constructor: function(interval) { var me = this; if (typeof interval == 'number') { me.interval = interval; } else if (interval) { Ext.apply(me, interval); } me.tasks = []; me.timerFn = Ext.Function.bind(me.onTick, me); }, newTask: function(config) { var task = new Ext.util.TaskRunner.Task(config); task.manager = this; return task; }, start: function(task) { var me = this, now = Ext.Date.now(); if (!task.pending) { me.tasks.push(task); task.pending = true; } task.stopped = false; task.taskStartTime = now; task.taskRunTime = task.fireOnStart !== false ? 0 : task.taskStartTime; task.taskRunCount = 0; if (!me.firing) { if (task.fireOnStart !== false) { me.startTimer(0, now); } else { me.startTimer(task.interval, now); } } return task; }, stop: function(task) { if (!task.stopped) { task.stopped = true; if (task.onStop) { task.onStop.call(task.scope || task, task); } } return task; }, stopAll: function() { Ext.each(this.tasks, this.stop, this); }, firing: false, nextExpires: 1.0E99, onTick: function() { var me = this, tasks = me.tasks, now = Ext.Date.now(), nextExpires = 1.0E99, len = tasks.length, globalEvents = Ext.GlobalEvents, expires, newTasks, i, task, rt, remove, fireIdleEvent; me.timerId = null; me.firing = true; for (i = 0; i < len || i < (len = tasks.length); ++i) { task = tasks[i]; if (!(remove = task.stopped)) { expires = task.taskRunTime + task.interval; if (expires <= now) { rt = 1; if (task.hasOwnProperty('fireIdleEvent')) { fireIdleEvent = task.fireIdleEvent; } else { fireIdleEvent = me.fireIdleEvent; } try { rt = task.run.apply(task.scope || task, task.args || [ ++task.taskRunCount ]); } catch (taskError) { try { Ext.log({ fn: task.run, prefix: 'Error while running task', stack: taskError.stack, msg: taskError, level: 'error' }); if (task.onError) { rt = task.onError.call(task.scope || task, task, taskError); } } catch (ignore) {} } task.taskRunTime = now; if (rt === false || task.taskRunCount === task.repeat) { me.stop(task); remove = true; } else { remove = task.stopped; expires = now + task.interval; } } if (!remove && task.duration && task.duration <= (now - task.taskStartTime)) { me.stop(task); remove = true; } } if (remove) { task.pending = false; if (!newTasks) { newTasks = tasks.slice(0, i); } } else { if (newTasks) { newTasks.push(task); } if (nextExpires > expires) { nextExpires = expires; } } } if (newTasks) { me.tasks = newTasks; } me.firing = false; if (me.tasks.length) { me.startTimer(nextExpires - now, Ext.Date.now()); } if (fireIdleEvent !== false && globalEvents.hasListeners.idle) { globalEvents.fireEvent('idle'); } }, startTimer: function(timeout, now) { var me = this, expires = now + timeout, timerId = me.timerId; if (timerId && me.nextExpires - expires > me.interval) { clearTimeout(timerId); timerId = null; } if (!timerId) { if (timeout < me.interval) { timeout = me.interval; } me.timerId = Ext.defer(me.timerFn, timeout); me.nextExpires = expires; } } }, function() { var me = this, proto = me.prototype; proto.destroy = proto.stopAll; me.Task = new Ext.Class({ isTask: true, stopped: true, fireOnStart: false, constructor: function(config) { Ext.apply(this, config); }, restart: function(interval) { if (interval !== undefined) { this.interval = interval; } this.manager.start(this); }, start: function(interval) { if (this.stopped) { this.restart(interval); } }, stop: function() { this.manager.stop(this); } }); proto = me.Task.prototype; proto.destroy = proto.stop; }); Ext.define('Ext.fx.target.Target', { isAnimTarget: true, constructor: function(target) { this.target = target; this.id = this.getId(); }, getId: function() { return this.target.id; }, remove: function() { Ext.destroy(this.target); } }); 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 ln = targetData.length, attrs, attr, o, i, j, ln2; 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]; this.setElVal(o[0], attr, o[1]); } } } } }, setElVal: function(element, attr, value) { 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 if (attr === 'width') { element.setWidth(value); } else if (attr === 'height') { element.setHeight(value); } else { element.setStyle(attr, value); } } }); Ext.define('Ext.fx.target.ElementCSS', { extend: 'Ext.fx.target.Element', setAttr: function(targetData, isFirstFrame) { var cssArr = { attrs: [], duration: [], easing: [] }, ln = targetData.length, cleanerFn = function() { this.setStyle(Ext.supports.CSS3Prefix + 'TransitionProperty', null); this.setStyle(Ext.supports.CSS3Prefix + 'TransitionDuration', null); this.setStyle(Ext.supports.CSS3Prefix + 'TransitionTimingFunction', null); }, single = { single: true }, 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 (isFirstFrame) { o = o[0].dom.offsetWidth; } else { o[0].on(Ext.supports.CSS3TransitionEnd, cleanerFn, o[0], single); } } } } } }); 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, elements = target.elements, length = elements.length, i, el; for (i = 0; i < length; i++) { el = elements[i]; if (el) { el = target.getElement(el); out.push([ el, this.getElVal(el, attr, val) ]); } } return out; }, setAttr: function(targetData) { var target = this.target, ln = targetData.length, elements = target.elements, ln3 = elements.length, value, k, attrs, attr, el, i, j, ln2; 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++) { value = attrs[attr][j][1]; for (k = 0; k < ln3; ++k) { el = elements[k]; if (el) { el = target.getElement(el); this.setElVal(el, attr, value); } } } } } } }, remove: function() { this.target.destroy(); } }); Ext.define('Ext.fx.target.CompositeElementCSS', { extend: 'Ext.fx.target.CompositeElement', requires: [ 'Ext.fx.target.ElementCSS' ], setAttr: function() { return Ext.fx.target.ElementCSS.prototype.setAttr.apply(this, arguments); } }); Ext.define('Ext.fx.target.Sprite', { extend: 'Ext.fx.target.Target', type: 'draw', getFromPrim: function(sprite, attr) { var obj; switch (attr) { case 'rotate': case 'rotation': obj = sprite.attr.rotation; return { x: obj.x || 0, y: obj.y || 0, degrees: obj.degrees || 0 }; case 'scale': case 'scaling': obj = sprite.attr.scaling; return { x: obj.x || 1, y: obj.y || 1, cx: obj.cx || 0, cy: obj.cy || 0 }; case 'translate': case 'translation': obj = sprite.attr.translation; return { x: obj.x || 0, y: obj.y || 0 }; default: return sprite.attr[attr]; } }, getAttr: function(attr, val) { return [ [ this.target, val !== undefined ? val : this.getFromPrim(this.target, attr) ] ]; }, setAttr: function(targetData) { var ln = targetData.length, spriteArr = [], attrsConf, attr, attrArr, attrs, sprite, idx, value, i, j, x, y, ln2; for (i = 0; i < ln; i++) { attrsConf = targetData[i].attrs; for (attr in attrsConf) { attrArr = attrsConf[attr]; ln2 = attrArr.length; for (j = 0; j < ln2; j++) { sprite = attrArr[j][0]; attrs = attrArr[j][1]; if (attr === 'translate' || attr === 'translation') { value = { x: attrs.x, y: attrs.y }; } else if (attr === 'rotate' || attr === 'rotation') { x = attrs.x; if (isNaN(x)) { x = null; } y = attrs.y; if (isNaN(y)) { y = null; } value = { degrees: attrs.degrees, x: x, y: y }; } else if (attr === 'scale' || attr === 'scaling') { x = attrs.x; if (isNaN(x)) { x = null; } y = attrs.y; if (isNaN(y)) { y = null; } value = { x: x, y: y, cx: attrs.cx, cy: attrs.cy }; } else if (attr === 'width' || attr === 'height' || attr === 'x' || attr === 'y') { value = parseFloat(attrs); } else { value = attrs; } idx = Ext.Array.indexOf(spriteArr, sprite); if (idx === -1) { spriteArr.push([ sprite, {} ]); idx = spriteArr.length - 1; } spriteArr[idx][1][attr] = value; } } } ln = spriteArr.length; for (i = 0; i < ln; i++) { spriteArr[i][0].setAttributes(spriteArr[i][1]); } this.target.redraw(); } }); Ext.define('Ext.fx.target.CompositeSprite', { extend: 'Ext.fx.target.Sprite', getAttr: function(attr, val) { var out = [], sprites = [].concat(this.target.items), length = sprites.length, i, sprite; for (i = 0; i < length; i++) { sprite = sprites[i]; out.push([ sprite, val !== undefined ? val : this.getFromPrim(sprite, attr) ]); } 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'); } }, setMethods: { 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, ln = targetData.length, attrs, attr, o, i, j, targets, left, top, w, h, methodsToCall = {}, methodProps; for (i = 0; i < ln; i++) { attrs = targetData[i].attrs; for (attr in attrs) { targets = attrs[attr].length; for (j = 0; j < targets; j++) { o = attrs[attr][j]; methodProps = methodsToCall[me.setMethods[attr]] || (methodsToCall[me.setMethods[attr]] = {}); methodProps.target = o[0]; methodProps[attr] = o[1]; } } if (methodsToCall.setPosition) { o = methodsToCall.setPosition; left = (o.left === undefined) ? undefined : parseFloat(o.left); top = (o.top === undefined) ? undefined : parseFloat(o.top); o.target.setPosition(left, top); } if (methodsToCall.setPagePosition) { o = methodsToCall.setPagePosition; o.target.setPagePosition(o.x, o.y); } if (methodsToCall.setSize) { o = methodsToCall.setSize; w = (o.width === undefined) ? o.target.getWidth() : parseFloat(o.width); h = (o.height === undefined) ? o.target.getHeight() : parseFloat(o.height); o.target.el.setSize(w, h); if (isLastFrame || me.dynamic) { Ext.GlobalEvents.on({ idle: Ext.Function.bind(o.target.setSize, o.target, [ w, h ]), single: true }); } } if (methodsToCall.setOpacity) { o = methodsToCall.setOpacity; o.target.el.setStyle('opacity', o.opacity); } } } }); Ext.define('Ext.fx.Queue', { requires: [ 'Ext.util.HashMap' ], constructor: function() { this.targets = new 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 (queue.length === 0) { me.targets.remove(anim.target); } if (anim.remove) { if (target.type === 'element') { var el = Ext.get(target.id); if (el) { el.destroy(); } } } }, me, { single: true }); queue.push(anim); } }); Ext.define('Ext.fx.Manager', { singleton: true, requires: [ 'Ext.util.MixedCollection', 'Ext.util.TaskRunner', 'Ext.fx.target.Element', 'Ext.fx.target.ElementCSS', 'Ext.fx.target.CompositeElement', 'Ext.fx.target.CompositeElementCSS', 'Ext.fx.target.Sprite', 'Ext.fx.target.CompositeSprite', 'Ext.fx.target.Component' ], mixins: { queue: 'Ext.fx.Queue' }, constructor: function() { var me = this; me.items = new Ext.util.MixedCollection(); me.targetArr = {}; me.mixins.queue.constructor.call(me); me.taskRunner = new Ext.util.TaskRunner(); }, interval: 16, forceJS: true, createTarget: function(target) { var me = this, useCSS3 = !me.forceJS && Ext.supports.Transitions, targetObj; me.useCSS3 = useCSS3; if (target) { if (target.tagName || Ext.isString(target) || target.isFly) { target = Ext.get(target); targetObj = new Ext.fx.target['Element' + (useCSS3 ? 'CSS' : '')](target); } else if (target.dom) { targetObj = new Ext.fx.target['Element' + (useCSS3 ? 'CSS' : '')](target); } else if (target.isComposite) { targetObj = new Ext.fx.target['CompositeElement' + (useCSS3 ? 'CSS' : '')](target); } else if (target.isSprite) { targetObj = new Ext.fx.target.Sprite(target); } else if (target.isCompositeSprite) { targetObj = new Ext.fx.target.CompositeSprite(target); } else if (target.isComponent) { targetObj = new 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 me = this, items = me.items, task = me.task; items.add(anim.id, anim); if (!task && items.length) { task = me.task = { run: me.runner, interval: me.interval, scope: me }; me.taskRunner.start(task); } }, removeAnim: function(anim) { var me = this, items = me.items, task = me.task; items.removeAtKey(anim.id); if (task && !items.length) { me.taskRunner.stop(task); delete me.task; } }, runner: function() { var me = this, items = me.items.getRange(), i = 0, len = items.length, anim; me.targetArr = {}; me.timestamp = new Date(); for (; i < len; i++) { anim = items[i]; if (anim.isReady()) { me.startAnim(anim); } } for (i = 0; i < len; i++) { anim = items[i]; if (anim.isRunning()) { me.runAnim(anim); } } me.applyPendingAttrs(); }, startAnim: function(anim) { anim.start(this.timestamp); }, runAnim: function(anim, forceEnd) { if (!anim) { return; } var me = this, useCSS3 = me.useCSS3 && anim.target.type === 'element', elapsedTime = me.timestamp - anim.startTime, lastFrame = (elapsedTime >= anim.duration), target, o; if (forceEnd) { elapsedTime = anim.duration; lastFrame = true; } target = this.collectTargetData(anim, elapsedTime, useCSS3, lastFrame); if (useCSS3) { anim.target.setAttr(target.anims[anim.id].attributes, true); me.collectTargetData(anim, anim.duration, useCSS3, lastFrame); 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); } return target; }, jumpToEnd: function(anim) { var target = this.runAnim(anim, true); this.applyAnimAttrs(target, target.anims[anim.id]); }, collectTargetData: function(anim, elapsedTime, useCSS3, isLastFrame) { var targetId = anim.target.getId(), target = this.targetArr[targetId]; if (!target) { target = this.targetArr[targetId] = { id: targetId, el: anim.target, anims: {} }; } target.anims[anim.id] = { id: anim.id, anim: anim, elapsed: elapsedTime, isLastFrame: isLastFrame, attributes: [ { duration: anim.duration, easing: (useCSS3 && anim.reverse) ? anim.easingFn.reverse().toCSS3() : anim.easing, attrs: anim.runAnim(elapsedTime) } ] }; return target; }, applyAnimAttrs: function(target, animWrap) { var anim = animWrap.anim; if (animWrap.attributes && anim.isRunning()) { target.el.setAttr(animWrap.attributes, false, animWrap.isLastFrame); if (animWrap.isLastFrame) { anim.lastFrame(); } } }, applyPendingAttrs: function() { var targetArr = this.targetArr, target, targetId, animWrap, anim, animId; for (targetId in targetArr) { if (targetArr.hasOwnProperty(targetId)) { target = targetArr[targetId]; for (animId in target.anims) { if (target.anims.hasOwnProperty(animId)) { animWrap = target.anims[animId]; anim = animWrap.anim; if (animWrap.attributes && anim.isRunning()) { target.el.setAttr(animWrap.attributes, false, animWrap.isLastFrame); if (animWrap.isLastFrame) { anim.lastFrame(); } } } } } } } }); 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.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, 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, ln = timeline.length, anim, easing, damper, attrs, 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 = new 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); }, isReady: function() { return this.paused === false && this.running === false && this.iterations > 0; }, isRunning: function() { return false; } }); 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) < 1.0E-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.fx.Easing', function() { var math = Math, pi = math.PI, pow = math.pow, sin = math.sin, sqrt = math.sqrt, abs = math.abs, backInSeed = 1.70158; return { requires: [ 'Ext.fx.CubicBezier' ], singleton: true, linear: Ext.identityFn, ease: function(n) { var q = 0.07813 - n / 2, 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; } }; }, function(me) { var Easing = me.self, proto = Easing.prototype; Easing.addMembers({ 'back-in': proto.backIn, 'back-out': proto.backOut, 'ease-in': proto.easeIn, 'ease-out': proto.easeOut, 'elastic-in': proto.elasticIn, 'elastic-out': proto.elasticOut, 'bounce-in': proto.bounceIn, 'bounce-out': proto.bounceOut, 'ease-in-out': proto.easeInOut }); }); Ext.define('Ext.fx.DrawPath', { singleton: true, 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, 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; }, path2string: function() { return this.join(",").replace(Ext.fx.DrawPath.pathToStringRE, "$1"); }, pathToString: function(arrayPath) { return arrayPath.join(",").replace(Ext.fx.DrawPath.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) { if (b) { params.push(+b); } }); if (name == "m" && params.length > 2) { data.push([ b ].concat(Ext.Array.splice(params, 0, 2))); name = "l"; b = (b == "m") ? "l" : "L"; } while (params.length >= paramCounts[name]) { data.push([ b ].concat(Ext.Array.splice(params, 0, paramCounts[name]))); if (!paramCounts[name]) { break; } } }); } data.toString = me.path2string; return data; }, 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, i = 0, ln = pathArray.length, r, pathSegment, j, ln2; if (ln && pathArray[0][0] == "M") { x = +pathArray[0][1]; y = +pathArray[0][2]; mx = x; my = y; i++; res[0] = [ "M", x, y ]; } for (; i < ln; i++) { r = res[i] = []; pathSegment = pathArray[i]; if (pathSegment[0] != pathSegment[0].toUpperCase()) { r[0] = pathSegment[0].toUpperCase(); switch (r[0]) { case "A": r[1] = pathSegment[1]; r[2] = pathSegment[2]; r[3] = pathSegment[3]; r[4] = pathSegment[4]; r[5] = pathSegment[5]; r[6] = +(pathSegment[6] + x); r[7] = +(pathSegment[7] + y); break; case "V": r[1] = +pathSegment[1] + y; break; case "H": r[1] = +pathSegment[1] + x; break; case "M": mx = +pathSegment[1] + x; my = +pathSegment[2] + y; default: j = 1; ln2 = pathSegment.length; for (; j < ln2; j++) { r[j] = +pathSegment[j] + ((j % 2) ? x : y); }; } } else { j = 0; ln2 = pathSegment.length; for (; j < ln2; j++) { res[i][j] = pathSegment[j]; } } switch (r[0]) { case "Z": x = mx; y = my; break; case "H": x = r[1]; break; case "V": y = r[1]; break; case "M": pathSegment = res[i]; ln2 = pathSegment.length; mx = pathSegment[ln2 - 2]; my = pathSegment[ln2 - 1]; default: pathSegment = res[i]; ln2 = pathSegment.length; x = pathSegment[ln2 - 2]; y = pathSegment[ln2 - 1]; } } res.toString = this.path2string; return res; }, 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) { Ext.Array.splice(pp, i++, 0, [ "C" ].concat(Ext.Array.splice(pi, 0, 6))); } Ext.Array.erase(pp, i, 1); ii = Math.max(p.length, p2.length || 0); } }, fixM = function(path1, path2, a1, a2, i) { if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") { Ext.Array.splice(path2, 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); } }, i, ii, seg, seg2, seglen, seg2len; for (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); 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, 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; 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; } } }); Ext.define('Ext.fx.PropertyHandler', { requires: [ 'Ext.fx.DrawPath' ], statics: { defaultHandler: { pixelDefaultsRE: /width|height|top$|bottom$|left$|right$/i, unitRE: /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/, scrollRE: /^scroll/i, computeDelta: function(from, end, damper, initial, attr) { damper = (typeof damper == 'number') ? damper : 1; var unitRE = this.unitRE, match = unitRE.exec(from), start, units; if (match) { from = match[1]; units = match[2]; if (!this.scrollRE.test(attr) && !units && this.pixelDefaultsRE.test(attr)) { units = 'px'; } } from = +from || 0; match = 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; } }, stringHandler: { computeDelta: function(from, end, damper, initial, attr) { return { from: from, delta: end }; }, get: function(from, end, damper, initialFrom, attr) { var ln = from.length, out = [], i, initial; for (i = 0; i < ln; i++) { 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; for (i = 0; i < ln; i++) { val = values[i][1]; out.push([ values[i][0], val.delta ]); } 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 out = false, reList = [ this.hexRE, this.rgbRE, this.hex3RE ], length = reList.length, match, base, re, i; for (i = 0; i < length; i++) { re = reList[i]; base = (i % 2 === 0) ? 16 : 10; match = re.exec(color); if (match && match.length === 4) { if (i === 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) }; break; } } 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] = parseFloat(prop[p]) * 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] = 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.fx.DrawPath.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.fx.DrawPath.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() { var props = [ 'outlineColor', 'backgroundColor', 'borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'fill', 'stroke' ], length = props.length, i = 0, prop; for (; i < length; i++) { prop = props[i]; this[prop] = this.color; } props = [ 'cursor' ]; length = props.length; i = 0; for (; i < length; i++) { prop = props[i]; this[prop] = this.stringHandler; } }); 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, autoEnd: false, alternate: false, currentIteration: 0, startTime: 0, frameCount: 0, constructor: function(config) { var me = this, curve; config = config || {}; if (config.keyframes) { return new Ext.fx.Animator(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) { curve = me.easingFn; me.easingFn = Ext.fx.CubicBezier.cubicBezier(+curve[1], +curve[2], +curve[3], +curve[4]); } } me.id = Ext.id(null, 'ext-anim-'); me.mixins.observable.constructor.call(me); Ext.fx.Manager.addAnim(me); if (config.autoEnd) { me.running = true; me.jumpToEnd(); } }, 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; me.frameCount = 0; } }, jumpToEnd: function() { var me = this; if (!me.endWasCalled) { if (!me.currentAttrs) { me.initAttrs(); } Ext.fx.Manager.jumpToEnd(me); me.end(); } }, 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); } } me.frameCount++; 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); } }, endWasCalled: 0, end: function() { var me = this; if (me.endWasCalled++) { return; } me.startTime = 0; me.paused = false; me.running = false; Ext.fx.Manager.removeAnim(me); me.fireEvent('afteranimate', me, me.startTime); Ext.callback(me.callback, me.scope, [ me, me.startTime ]); if (me.remove) { me.target.destroy(); } }, isReady: function() { return this.paused === false && this.running === false && this.iterations > 0; }, isRunning: function() { return this.paused === false && this.running === true && this.isAnimator !== true; } }); Ext.enableFx = true; Ext.define('Ext.util.Animate', { mixinId: 'animate', requires: [ 'Ext.fx.Manager', 'Ext.fx.Anim' ], isAnimate: true, animate: function(animObj) { var me = this; if (Ext.fx.Manager.hasFxBlock(me.id)) { return me; } Ext.fx.Manager.queueFx(new 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); }, getAnimationProps: function() { var me = this, layout = me.layout; return layout && layout.animate ? layout.animate : {}; }, stopFx: Ext.Function.alias(Ext.util.Animate, 'stopAnimation'), stopAnimation: function() { Ext.fx.Manager.stopAnimation(this.id); return this; }, syncFx: function() { Ext.fx.Manager.setFxDefaults(this.id, { concurrent: true }); return this; }, sequenceFx: function() { Ext.fx.Manager.setFxDefaults(this.id, { concurrent: false }); return this; }, hasActiveFx: Ext.Function.alias(Ext.util.Animate, 'getActiveAnimation'), getActiveAnimation: function() { return Ext.fx.Manager.getActiveAnimation(this.id); } }); Ext.define('Ext.dom.Fly', { extend: 'Ext.dom.Element', alternateClassName: 'Ext.dom.Element.Fly', validNodeTypes: { 1: 1, 9: 1, 11: 1 }, isFly: true, constructor: function(dom) { this.dom = dom; this.el = this; }, attach: function(dom) { var me = this; if (!dom) { return me.detach(); } me.dom = dom; if (!Ext.cache[dom.id]) { me.getData().isSynchronized = false; } return me; }, detach: function() { this.dom = null; }, addListener: function() { Ext.Error.raise("Cannot use addListener() on Ext.dom.Fly instances. " + "Please use Ext.get() to retrieve an Ext.dom.Element instance instead."); } || null, removeListener: function() { Ext.Error.raise("Cannot use removeListener() on Ext.dom.Fly instances. " + "Please use Ext.get() to retrieve an Ext.dom.Element instance instead."); } || null }, function(Fly) { var flyweights = {}; Fly.cache = flyweights; Ext.fly = function(dom, named) { var fly = null, fn = Ext.fly, nodeType, data; named = named || (fn.caller && fn.caller.$name) || '_global'; dom = Ext.getDom(dom); if (dom) { nodeType = dom.nodeType; if (Fly.prototype.validNodeTypes[nodeType] || (!nodeType && (dom.window == dom))) { fly = Ext.cache[dom.id]; if (!fly || fly.dom !== dom) { fly = flyweights[named] || (flyweights[named] = new Fly()); fly.dom = dom; data = fly.getData(true); if (data) { data.isSynchronized = false; } } } } return fly; }; }); Ext.define('Ext.dom.CompositeElementLite', { alternateClassName: [ 'Ext.CompositeElementLite' ], requires: [ 'Ext.dom.Fly' ], isComposite: true, isLite: true, statics: { importElementMethods: function() { var Element = Ext.dom.Element, prototype = this.prototype; Ext.Object.each(Element.prototype, function(name, member) { if (typeof member === 'function' && !prototype[name]) { prototype[name] = function() { return this.invoke(name, arguments); }; } }); } }, constructor: function(elements, skipValidation) { if (skipValidation) { this.elements = elements || []; } else { this.elements = []; this.add(elements); } }, getElement: function(el) { var fly = this._fly || (this._fly = new Ext.dom.Fly()); return fly.attach(el); }, transformElement: function(el) { return Ext.getDom(el); }, getCount: function() { return this.elements.length; }, add: function(els, root) { var elements = this.elements, i, ln; if (!els) { return this; } if (typeof els == "string") { els = Ext.fly(root || document).query(els); } else if (els.isComposite) { els = els.elements; } else if (!Ext.isIterable(els)) { els = [ els ]; } for (i = 0 , ln = els.length; i < ln; ++i) { elements.push(this.transformElement(els[i])); } return this; }, invoke: function(fn, args) { var me = this, elements = me.elements, ln = elements.length, prototype, element, i; if (i !== 0) { prototype = (me.isLite ? Ext.dom.Fly : Ext.dom.Element).prototype; for (i = 0; i < ln; i++) { element = elements[i]; if (element) { prototype[fn].apply(me.getElement(element), args); } } } return me; }, item: function(index) { var el = this.elements[index], out = null; if (el) { out = this.getElement(el); } return out; }, slice: function(start, end) { return Ext.Array.slice(this.elements, start, end); }, each: function(fn, scope) { var me = this, els = me.elements, len = els.length, i, e; for (i = 0; i < len; i++) { e = els[i]; if (e) { e = this.getElement(e); if (fn.call(scope || e, e, me, i) === false) { break; } } } return me; }, fill: function(els) { var me = this; me.elements = []; me.add(els); return me; }, insert: function(index, nodes) { Ext.Array.insert(this.elements, index, nodes); }, filter: function(selector) { var me = this, els = me.elements, len = els.length, out = [], i = 0, isFunc = typeof selector == 'function', add, el; for (; i < len; i++) { el = els[i]; add = false; if (el) { el = me.getElement(el); if (isFunc) { add = selector.call(el, el, me, i) !== false; } else { add = el.is(selector); } if (add) { out.push(me.transformElement(el)); } } } me.elements = out; return me; }, indexOf: function(el) { return Ext.Array.indexOf(this.elements, this.transformElement(el)); }, replaceElement: function(el, replacement, domReplace) { var index = !isNaN(el) ? el : this.indexOf(el), d; if (index > -1) { replacement = Ext.getDom(replacement); if (domReplace) { d = this.elements[index]; d.parentNode.insertBefore(replacement, d); Ext.removeNode(d); } Ext.Array.splice(this.elements, index, 1, replacement); } return this; }, clear: function(removeDom) { var me = this, els = me.elements, i = els.length - 1; if (removeDom) { for (; i >= 0; i--) { Ext.removeNode(els[i]); } } this.elements = []; }, addElements: function(els, root) { if (!els) { return this; } if (typeof els === "string") { els = Ext.dom.Element.selectorFunction(els, root); } var yels = this.elements, eLen = els.length, e; for (e = 0; e < eLen; e++) { yels.push(Ext.get(els[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) { keys = [].concat(keys); var me = this, elements = me.elements, kLen = keys.length, val, el, k; for (k = 0; k < kLen; k++) { val = keys[k]; if ((el = (elements[val] || elements[val = me.indexOf(val)]))) { if (removeDom) { if (el.dom) { el.destroy(); } else { Ext.removeNode(el); } } Ext.Array.erase(elements, val, 1); } } return me; }, destroy: function() { return this.invoke('destroy', arguments); } }, function(CompositeElementLite) { var prototype = CompositeElementLite.prototype; CompositeElementLite.importElementMethods(); prototype.on = prototype.addListener; }); Ext.define('Ext.overrides.dom.Element', (function() { var Element, WIN = window, DOC = document, HIDDEN = 'hidden', ISCLIPPED = 'isClipped', OVERFLOW = 'overflow', OVERFLOWX = 'overflow-x', OVERFLOWY = 'overflow-y', ORIGINALCLIP = 'originalClip', HEIGHT = 'height', WIDTH = 'width', VISIBILITY = 'visibility', DISPLAY = 'display', NONE = 'none', OFFSETS = 'offsets', ORIGINALDISPLAY = 'originalDisplay', VISMODE = 'visibilityMode', ISVISIBLE = 'isVisible', OFFSETCLASS = Ext.baseCSSPrefix + 'hidden-offsets', boxMarkup = [ '', '', '' ].join(''), scriptTagRe = /(?:]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig, replaceScriptTagRe = /(?:)((\n|\r|.)*?)(?:<\/script>)/ig, srcRe = /\ssrc=([\'\"])(.*?)\1/i, nonSpaceRe = /\S/, typeRe = /\stype=([\'\"])(.*?)\1/i, msRe = /^-ms-/, camelRe = /(-[a-z])/gi, camelReplaceFn = function(m, a) { return a.charAt(1).toUpperCase(); }, XMASKED = Ext.baseCSSPrefix + "masked", XMASKEDRELATIVE = Ext.baseCSSPrefix + "masked-relative", EXTELMASKMSG = Ext.baseCSSPrefix + "mask-msg", bodyRe = /^body/i, propertyCache = {}, getDisplay = function(el) { var data = el.getData(), display = data[ORIGINALDISPLAY]; if (display === undefined) { data[ORIGINALDISPLAY] = display = ''; } return display; }, getVisMode = function(el) { var data = el.getData(), visMode = data[VISMODE]; if (visMode === undefined) { data[VISMODE] = visMode = Element.VISIBILITY; } return visMode; }, emptyRange = DOC.createRange ? DOC.createRange() : null, inputTags = { INPUT: true, TEXTAREA: true }; if (Ext.isIE8) { var removeNode = Ext.removeNode, garbageBin = DOC.createElement('div'), destroyQueue = [], clearGarbage = Ext.Function.createBuffered(function() { var len = destroyQueue.length, i; for (i = 0; i < len; i++) { garbageBin.appendChild(destroyQueue[i]); } garbageBin.innerHTML = ''; destroyQueue.length = 0; }, 10); Ext.removeNode = function(node) { node = node.dom || node; removeNode(node); destroyQueue[destroyQueue.length] = node; clearGarbage(); }; } return { override: 'Ext.dom.Element', mixins: [ 'Ext.util.Animate' ], uses: [ 'Ext.dom.GarbageCollector', 'Ext.dom.Fly', 'Ext.event.publisher.MouseEnterLeave', 'Ext.fx.Manager', 'Ext.fx.Anim' ], skipGarbageCollection: false, _init: function(E) { Element = E; }, statics: { selectableCls: Ext.baseCSSPrefix + 'selectable', unselectableCls: Ext.baseCSSPrefix + 'unselectable', tabIndexAttributeName: Ext.isIE8 ? 'tabIndex' : 'tabindex', tabbableSelector: 'a[href],button,iframe,input,select,textarea,[tabindex],[contenteditable="true"]', naturallyFocusableTags: { BUTTON: true, IFRAME: true, EMBED: true, INPUT: true, OBJECT: true, SELECT: true, TEXTAREA: true, HTML: Ext.isIE ? true : false }, naturallyTabbableTags: { BUTTON: true, IFRAME: true, INPUT: true, SELECT: true, TEXTAREA: true, OBJECT: Ext.isIE8m ? true : false }, tabbableSavedFlagAttribute: 'data-tabindexsaved', tabbableSavedAttribute: 'data-savedtabindex', normalize: function(prop) { if (prop === 'float') { prop = Ext.supports.Float ? 'cssFloat' : 'styleFloat'; } return propertyCache[prop] || (propertyCache[prop] = prop.replace(msRe, 'ms-').replace(camelRe, camelReplaceFn)); }, getViewportHeight: function() { return Ext.isIE9m ? DOC.documentElement.clientHeight : WIN.innerHeight; }, getViewportWidth: function() { return (!Ext.isStrict && !Ext.isOpera) ? document.body.clientWidth : Ext.isIE9m ? DOC.documentElement.clientWidth : WIN.innerWidth; } }, addClsOnClick: function(className, testFn, scope) { var me = this, dom = me.dom, hasTest = Ext.isFunction(testFn); me.on("mousedown", function() { if (hasTest && testFn.call(scope || me, me) === false) { return false; } Ext.fly(dom).addCls(className); var d = Ext.getDoc(), fn = function() { Ext.fly(dom).removeCls(className); d.removeListener("mouseup", fn); }; d.on("mouseup", fn); }); return me; }, addClsOnFocus: function(className, testFn, scope) { var me = this, dom = me.dom, hasTest = Ext.isFunction(testFn); me.on("focus", function() { if (hasTest && testFn.call(scope || me, me) === false) { return false; } Ext.fly(dom).addCls(className); }); me.on("blur", function() { Ext.fly(dom).removeCls(className); }); return me; }, addClsOnOver: function(className, testFn, scope) { var me = this, dom = me.dom, hasTest = Ext.isFunction(testFn); me.hover(function() { if (hasTest && testFn.call(scope || me, me) === false) { return; } Ext.fly(dom).addCls(className); }, function() { Ext.fly(dom).removeCls(className); }); return me; }, addKeyListener: function(key, fn, scope) { var config; if (typeof key !== 'object' || Ext.isArray(key)) { config = { target: this, key: key, fn: fn, scope: scope }; } else { config = { target: this, key: key.key, shift: key.shift, ctrl: key.ctrl, alt: key.alt, fn: fn, scope: scope }; } return new Ext.util.KeyMap(config); }, addKeyMap: function(config) { return new Ext.util.KeyMap(Ext.apply({ target: this }, config)); }, afterAnimate: function() { var shadow = this.shadow; if (shadow && !shadow.disabled && !shadow.animate) { shadow.show(); } }, anchorAnimX: function(anchor) { var xName = (anchor === 'l') ? 'right' : 'left'; this.dom.style[xName] = '0px'; }, 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.dom, 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; }, animate: function(config) { var me = this, animId = me.dom.id || Ext.id(me.dom), listeners, anim, end; if (!Ext.fx.Manager.hasFxBlock(animId)) { if (config.listeners) { listeners = config.listeners; delete config.listeners; } if (config.internalListeners) { config.listeners = config.internalListeners; delete config.internalListeners; } end = config.autoEnd; delete config.autoEnd; anim = new Ext.fx.Anim(me.anim(config)); anim.on({ afteranimate: 'afterAnimate', beforeanimate: 'beforeAnimate', scope: me, single: true }); if (listeners) { anim.on(listeners); } Ext.fx.Manager.queueFx(anim); if (end) { anim.jumpToEnd(); } } return me; }, beforeAnimate: function() { var shadow = this.shadow; if (shadow && !shadow.disabled && !shadow.animate) { shadow.hide(); } }, boxWrap: function(cls) { cls = cls || Ext.baseCSSPrefix + 'box'; var el = Ext.get(this.insertHtml("beforeBegin", "")); el.selectNode('.' + cls + '-mc').appendChild(this.dom); return el; }, clean: function(forceReclean) { var me = this, dom = me.dom, data = me.getData(), n = dom.firstChild, ni = -1, nx; if (data.isCleaned && forceReclean !== true) { return me; } while (n) { nx = n.nextSibling; if (n.nodeType === 3) { if (!(nonSpaceRe.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').clean(); n.nodeIndex = ++ni; } n = nx; } data.isCleaned = true; return me; }, empty: emptyRange ? function() { var dom = this.dom; if (dom.firstChild) { emptyRange.setStartBefore(dom.firstChild); emptyRange.setEndAfter(dom.lastChild); emptyRange.deleteContents(); } } : function() { var dom = this.dom; while (dom.lastChild) { dom.removeChild(dom.lastChild); } }, clearListeners: function() { this.removeAnchor(); this.callParent(); }, clearPositioning: function(value) { value = value || ''; return this.setStyle({ left: value, right: value, top: value, bottom: value, 'z-index': '', position: 'static' }); }, createProxy: function(config, renderTo, matchBox) { config = (typeof config === 'object') ? config : { tag: "div", role: 'presentation', cls: config }; var me = this, proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) : Ext.DomHelper.insertBefore(me.dom, config, true); proxy.setVisibilityMode(Element.DISPLAY); proxy.hide(); if (matchBox && me.setBox && me.getBox) { proxy.setBox(me.getBox()); } return proxy; }, clearOpacity: function() { return this.setOpacity(''); }, clip: function() { var me = this, data = me.getData(), style; if (!data[ISCLIPPED]) { data[ISCLIPPED] = true; style = me.getStyle([ OVERFLOW, OVERFLOWX, OVERFLOWY ]); data[ORIGINALCLIP] = { o: style[OVERFLOW], x: style[OVERFLOWX], y: style[OVERFLOWY] }; me.setStyle(OVERFLOW, HIDDEN); me.setStyle(OVERFLOWX, HIDDEN); me.setStyle(OVERFLOWY, HIDDEN); } return me; }, destroy: function() { var me = this, dom = me.dom, data = me.getData(), maskEl, maskMsg; if (dom && me.isAnimate) { me.stopAnimation(); } me.callParent(); if (dom && Ext.isIE8 && (dom.window != dom) && (dom.nodeType !== 9) && (dom.tagName !== 'BODY') && (dom.tagName !== 'HTML')) { destroyQueue[destroyQueue.length] = dom; clearGarbage(); } if (data) { maskEl = data.maskEl; maskMsg = data.maskMsg; if (maskEl) { maskEl.destroy(); } if (maskMsg) { maskMsg.destroy(); } } }, enableDisplayMode: function(display) { var me = this; me.setVisibilityMode(Element.DISPLAY); if (display !== undefined) { me.getData()[ORIGINALDISPLAY] = display; } return me; }, fadeIn: function(o) { var me = this, dom = me.dom; me.animate(Ext.apply({}, o, { opacity: 1, internalListeners: { beforeanimate: function(anim) { var el = Ext.fly(dom, '_anim'); if (el.isStyle('display', 'none')) { el.setDisplayed(''); } else { el.show(); } } } })); return this; }, fadeOut: function(o) { var me = this, dom = me.dom; o = Ext.apply({ opacity: 0, internalListeners: { afteranimate: function(anim) { if (dom && anim.to.opacity === 0) { var el = Ext.fly(dom, '_anim'); if (o.useDisplay) { el.setDisplayed(false); } else { el.hide(); } } } } }, o); me.animate(o); return me; }, fixDisplay: function() { var me = this; if (me.isStyle(DISPLAY, NONE)) { me.setStyle(VISIBILITY, HIDDEN); me.setStyle(DISPLAY, getDisplay(me)); if (me.isStyle(DISPLAY, NONE)) { me.setStyle(DISPLAY, "block"); } } }, frame: function(color, count, obj) { var me = this, dom = me.dom, beforeAnim; color = color || '#C3DAF9'; count = count || 1; obj = obj || {}; beforeAnim = function() { var el = Ext.fly(dom, '_anim'), animScope = this, box, proxy, proxyAnim; el.show(); box = el.getBox(); proxy = Ext.getBody().createChild({ role: 'presentation', id: el.dom.id + '-anim-proxy', style: { position: 'absolute', 'pointer-events': 'none', 'z-index': 35000, border: '0px solid ' + color } }); proxyAnim = new 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.destroy(); animScope.end(); }); }; me.animate({ duration: (Math.max(obj.duration, 500) * 2) || 2000, listeners: { beforeanimate: { fn: beforeAnim } }, callback: obj.callback, scope: obj.scope }); return me; }, getColor: function(attr, defaultValue, prefix) { var v = this.getStyle(attr), color = prefix || prefix === '' ? prefix : '#', h, len, i = 0; if (!v || (/transparent|inherit/.test(v))) { return defaultValue; } if (/^r/.test(v)) { v = v.slice(4, v.length - 1).split(','); len = v.length; for (; i < len; i++) { h = parseInt(v[i], 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); }, getLoader: function() { var me = this, data = me.getData(), loader = data.loader; if (!loader) { data.loader = loader = new Ext.ElementLoader({ target: me }); } return loader; }, getPositioning: function(autoPx) { var styles = this.getStyle([ 'left', 'top', 'position', 'z-index' ]), dom = this.dom; if (autoPx) { if (styles.left === 'auto') { styles.left = dom.offsetLeft + 'px'; } if (styles.top === 'auto') { styles.top = dom.offsetTop + 'px'; } } return styles; }, ghost: function(anchor, obj) { var me = this, dom = me.dom, beforeAnim; anchor = anchor || "b"; beforeAnim = function() { var el = Ext.fly(dom, '_anim'), width = el.getWidth(), height = el.getHeight(), xy = el.getXY(), position = el.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() { var el = Ext.fly(dom, '_anim'); if (el) { el.hide(); el.clearOpacity(); el.setPositioning(position); } }); }; me.animate(Ext.applyIf(obj || {}, { duration: 500, easing: 'ease-out', listeners: { beforeanimate: beforeAnim } })); return me; }, hide: function(animate) { if (typeof animate === 'string') { this.setVisible(false, animate); return this; } this.setVisible(false, this.anim(animate)); return this; }, 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]; var el = Ext.fly(dom, '_anim'); el.clearOpacity(); el.show(); event = lns.beforeanimate; if (event) { fn = event.fn || event; return fn.apply(event.scope || lns.scope || WIN, arguments); } }, afteranimate: function() { if (dom) { dom.style[attr] = restore; } event = lns.afteranimate; if (event) { fn = event.fn || event; fn.apply(event.scope || lns.scope || WIN, arguments); } } }); me.animate(Ext.apply({}, o, { duration: 1000, easing: 'ease-in', from: from, to: to })); return me; }, 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; }, 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); }, initDDTarget: function(group, config, overrides) { var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config); return Ext.apply(dd, overrides); }, isFocusable: function() { var dom = this.dom, focusable = false, nodeName; if (dom && !dom.disabled) { nodeName = dom.nodeName; focusable = !!Ext.Element.naturallyFocusableTags[nodeName] || ((nodeName === 'A' || nodeName === 'LINK') && !!dom.href) || dom.getAttribute('tabindex') != null || dom.contentEditable === 'true'; if (Ext.isIE8 && nodeName === 'INPUT' && dom.type === 'hidden') { focusable = false; } focusable = focusable && this.isVisible(true); } return focusable; }, isInputField: function() { var dom = this.dom, contentEditable = dom.contentEditable; if ((inputTags[dom.tagName] && dom.type !== 'button') || (contentEditable === '' || contentEditable === 'true')) { return true; } return false; }, isTabbable: function() { var dom = this.dom, tabbable = false, nodeName, hasIndex, tabIndex; if (dom && !dom.disabled) { nodeName = dom.nodeName; tabIndex = dom.getAttribute('tabindex'); hasIndex = tabIndex != null; tabIndex -= 0; if (nodeName === 'A' || nodeName === 'LINK') { if (dom.href) { tabbable = hasIndex && tabIndex < 0 ? false : true; } else { if (dom.contentEditable === 'true') { tabbable = !hasIndex || (hasIndex && tabIndex >= 0) ? true : false; } else { tabbable = hasIndex && tabIndex >= 0 ? true : false; } } } else if (dom.contentEditable === 'true' || Ext.Element.naturallyTabbableTags[nodeName]) { tabbable = hasIndex && tabIndex < 0 ? false : true; } else { if (hasIndex && tabIndex >= 0) { tabbable = true; } } if (Ext.isIE8 && nodeName === 'INPUT' && dom.type === 'hidden') { tabbable = false; } tabbable = tabbable && (!this.component || this.component.isVisible(true)) && this.isVisible(true); } return tabbable; }, isMasked: function(deep) { var me = this, data = me.getData(), maskEl = data.maskEl, maskMsg = data.maskMsg, hasMask = false, parent; if (maskEl && maskEl.isVisible()) { if (maskMsg) { maskMsg.center(me); } hasMask = true; } else if (deep) { parent = me.findParentNode(); if (parent) { return Ext.fly(parent).isMasked(deep); } } return hasMask; }, isScrollable: function() { var dom = this.dom; return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth; }, load: function(options) { this.getLoader().load(options); return this; }, mask: function(msg, msgCls, elHeight) { var me = this, dom = me.dom, data = me.getData(), maskEl = data.maskEl, maskMsg; if (!(bodyRe.test(dom.tagName) && me.getStyle('position') === 'static')) { me.addCls(XMASKEDRELATIVE); } if (maskEl) { maskEl.destroy(); } maskEl = Ext.DomHelper.append(dom, { role: 'presentation', cls: Ext.baseCSSPrefix + "mask " + Ext.baseCSSPrefix + "border-box", children: { role: 'presentation', cls: msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG, cn: { tag: 'div', role: 'presentation', cls: Ext.baseCSSPrefix + 'mask-msg-inner', cn: { tag: 'div', role: 'presentation', cls: Ext.baseCSSPrefix + 'mask-msg-text', html: msg || '' } } } }, true); maskMsg = Ext.get(maskEl.dom.firstChild); data.maskEl = maskEl; me.addCls(XMASKED); maskEl.setDisplayed(true); if (typeof msg === 'string') { maskMsg.setDisplayed(true); maskMsg.center(me); } else { maskMsg.setDisplayed(false); } if (dom === DOC.body) { maskEl.addCls(Ext.baseCSSPrefix + 'mask-fixed'); } else { me.saveTabbableState(); } me.saveChildrenTabbableState(); if (Ext.isIE9m && dom !== DOC.body && me.isStyle('height', 'auto')) { maskEl.setSize(undefined, elHeight || me.getHeight()); } return maskEl; }, monitorMouseLeave: function(delay, handler, scope) { var me = this, timer, listeners = { mouseleave: function(e) { if (Ext.isIE9m) { e.enableIEAsync(); } timer = Ext.defer(handler, delay, scope || me, [ e ]); }, mouseenter: function() { clearTimeout(timer); } }; me.on(listeners); return listeners; }, puff: function(obj) { var me = this, dom = me.dom, beforeAnim, box = me.getBox(), originalStyles = me.getStyle([ 'width', 'height', 'left', 'right', 'top', 'bottom', 'position', 'z-index', 'font-size', 'opacity' ], true); obj = Ext.applyIf(obj || {}, { easing: 'ease-out', duration: 500, useDisplay: false }); beforeAnim = function() { var el = Ext.fly(dom, '_anim'); el.clearOpacity(); el.show(); 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() { var el = Ext.fly(dom, '_anim'); if (el) { if (obj.useDisplay) { el.setDisplayed(false); } else { el.hide(); } el.setStyle(originalStyles); Ext.callback(obj.callback, obj.scope); } }); }; me.animate({ duration: obj.duration, easing: obj.easing, listeners: { beforeanimate: { fn: beforeAnim } } }); return me; }, selectable: function() { var me = this; me.dom.unselectable = ''; me.removeCls(Element.unselectableCls); me.addCls(Element.selectableCls); return me; }, setCapture: function() { var dom = this.dom; if (Ext.isIE9m && dom.setCapture) { dom.setCapture(); } }, setDisplayed: function(value) { var me = this; if (typeof value === "boolean") { value = value ? getDisplay(me) : NONE; } me.setStyle(DISPLAY, value); if (me.shadow || me.shim) { me.setUnderlaysVisible(value !== NONE); } return me; }, setHeight: function(height, animate) { var me = this; if (!animate || !me.anim) { me.callParent(arguments); } else { if (!Ext.isObject(animate)) { animate = {}; } me.animate(Ext.applyIf({ to: { height: height } }, animate)); } return me; }, setHorizontal: function() { var me = this, cls = me.verticalCls; delete me.vertical; if (cls) { delete me.verticalCls; me.removeCls(cls); } delete me.setWidth; delete me.setHeight; if (!Ext.isIE8) { delete me.getWidth; delete me.getHeight; } delete me.styleHooks; }, updateText: function(text) { var me = this, dom, textNode; if (dom) { textNode = dom.firstChild; if (!textNode || (textNode.nodeType !== 3 || textNode.nextSibling)) { textNode = DOC.createTextNode(); me.empty(); dom.appendChild(textNode); } if (text) { textNode.data = text; } } }, setHtml: 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 = Ext.interval(function() { var hd, match, attrs, srcMatch, typeMatch, el, s; if (!(el = DOC.getElementById(id))) { return false; } clearInterval(interval); Ext.removeNode(el); hd = Ext.getHead().dom; while ((match = scriptTagRe.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) { (WIN.execScript || WIN.eval)(match[2]); } } Ext.callback(callback, me); }, 20); dom.innerHTML = html.replace(replaceScriptTagRe, ''); return me; }, setOpacity: function(opacity, animate) { var me = this; if (!me.dom) { return me; } if (!animate || !me.anim) { me.setStyle('opacity', opacity); } else { if (typeof animate != 'object') { animate = { duration: 350, easing: 'ease-in' }; } me.animate(Ext.applyIf({ to: { opacity: opacity } }, animate)); } return me; }, setPositioning: function(pc) { return this.setStyle(pc); }, setVertical: function(angle, cls) { var me = this, proto = Element.prototype; me.vertical = true; if (cls) { me.addCls(me.verticalCls = cls); } me.setWidth = proto.setHeight; me.setHeight = proto.setWidth; if (!Ext.isIE8) { me.getWidth = proto.getHeight; me.getHeight = proto.getWidth; } me.styleHooks = (angle === 270) ? proto.verticalStyleHooks270 : proto.verticalStyleHooks90; }, setSize: function(width, height, animate) { var me = this; if (Ext.isObject(width)) { animate = height; height = width.height; width = width.width; } if (!animate || !me.anim) { me.dom.style.width = Element.addUnits(width); me.dom.style.height = Element.addUnits(height); if (me.shadow || me.shim) { me.syncUnderlays(); } } else { if (animate === true) { animate = {}; } me.animate(Ext.applyIf({ to: { width: width, height: height } }, animate)); } return me; }, setVisible: function(visible, animate) { var me = this, dom = me.dom, visMode = getVisMode(me); if (typeof animate === 'string') { switch (animate) { case DISPLAY: visMode = Element.DISPLAY; break; case VISIBILITY: visMode = Element.VISIBILITY; break; case OFFSETS: visMode = Element.OFFSETS; break; } me.setVisibilityMode(visMode); animate = false; } if (!animate || !me.anim) { if (visMode === Element.DISPLAY) { return me.setDisplayed(visible); } else if (visMode === Element.OFFSETS) { me[visible ? 'removeCls' : 'addCls'](OFFSETCLASS); } else if (visMode === Element.VISIBILITY) { 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() { if (!visible) { Ext.fly(dom).setVisible(false).setOpacity(1); } }, to: { opacity: (visible) ? 1 : 0 } }, animate)); } me.getData()[ISVISIBLE] = visible; if (me.shadow || me.shim) { me.setUnderlaysVisible(visible); } return me; }, setWidth: function(width, animate) { var me = this; if (!animate || !me.anim) { me.callParent(arguments); } else { if (!Ext.isObject(animate)) { animate = {}; } me.animate(Ext.applyIf({ to: { width: width } }, animate)); } return me; }, setX: function(x, animate) { return this.setXY([ x, this.getY() ], animate); }, setXY: function(xy, animate) { var me = this; if (!animate || !me.anim) { me.callParent([ xy ]); } else { if (!Ext.isObject(animate)) { animate = {}; } me.animate(Ext.applyIf({ to: { x: xy[0], y: xy[1] } }, animate)); } return this; }, setY: function(y, animate) { return this.setXY([ this.getX(), y ], animate); }, show: function(animate) { if (typeof animate === 'string') { this.setVisible(true, animate); return this; } this.setVisible(true, this.anim(animate)); return this; }, slideIn: function(anchor, obj, slideOut) { var me = this, dom = me.dom, elStyle = dom.style, beforeAnim, wrapAnim, restoreScroll, wrapDomParentNode; anchor = anchor || "t"; obj = obj || {}; beforeAnim = function() { var animScope = this, listeners = obj.listeners, el = Ext.fly(dom, '_anim'), box, originalStyles, anim, wrap; if (!slideOut) { el.fixDisplay(); } box = el.getBox(); if ((anchor == 't' || anchor == 'b') && box.height === 0) { box.height = dom.scrollHeight; } else if ((anchor == 'l' || anchor == 'r') && box.width === 0) { box.width = dom.scrollWidth; } originalStyles = el.getStyle([ 'width', 'height', 'left', 'right', 'top', 'bottom', 'position', 'z-index' ], true); el.setSize(box.width, box.height); if (obj.preserveScroll) { restoreScroll = el.cacheScrollValues(); } wrap = el.wrap({ role: 'presentation', id: Ext.id() + '-anim-wrap-for-' + el.dom.id, style: { visibility: slideOut ? 'visible' : 'hidden' } }); wrapDomParentNode = wrap.dom.parentNode; wrap.setPositioning(el.getPositioning()); if (wrap.isStyle('position', 'static')) { wrap.position('relative'); } el.clearPositioning('auto'); wrap.clip(); if (restoreScroll) { restoreScroll(); } el.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' } }; me.anchorAnimX(anchor); 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' } }; me.anchorAnimX(anchor); 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'; me.anchorAnimX('l'); break; case 'bl': anim = { from: { y: box.y + box.height, width: '0px', height: '0px' }, to: { y: box.y, width: box.width + 'px', height: box.height + 'px' } }; me.anchorAnimX('l'); 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' } }; me.anchorAnimX('r'); break; case 'tr': anim = { from: { x: box.x + box.width, width: '0px', height: '0px' }, to: { x: box.x, width: box.width + 'px', height: box.height + 'px' } }; elStyle.bottom = '0px'; me.anchorAnimX('r'); break; } wrap.show(); wrapAnim = Ext.apply({}, obj); delete wrapAnim.listeners; wrapAnim = new 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() { var el = Ext.fly(dom, '_anim'); el.setStyle(originalStyles); if (slideOut) { if (obj.useDisplay) { el.setDisplayed(false); } else { el.hide(); } } if (wrap.dom) { if (wrap.dom.parentNode) { wrap.dom.parentNode.insertBefore(el.dom, wrap.dom); } else { wrapDomParentNode.appendChild(el.dom); } wrap.destroy(); } if (restoreScroll) { restoreScroll(); } animScope.end(); }); if (listeners) { wrapAnim.on(listeners); } }; me.animate({ duration: obj.duration ? Math.max(obj.duration, 500) * 2 : 1000, listeners: { beforeanimate: beforeAnim } }); return me; }, slideOut: function(anchor, o) { return this.slideIn(anchor, o, true); }, swallowEvent: function(eventName, preventDefault) { var me = this, e, eLen, fn = function(e) { e.stopPropagation(); if (preventDefault) { e.preventDefault(); } }; if (Ext.isArray(eventName)) { eLen = eventName.length; for (e = 0; e < eLen; e++) { me.on(eventName[e], fn); } return me; } me.on(eventName, fn); return me; }, switchOff: function(obj) { var me = this, dom = me.dom, beforeAnim; obj = Ext.applyIf(obj || {}, { easing: 'ease-in', duration: 500, remove: false, useDisplay: false }); beforeAnim = function() { var el = Ext.fly(dom, '_anim'), animScope = this, size = el.getSize(), xy = el.getXY(), keyframe, position; el.clearOpacity(); el.clip(); position = el.getPositioning(); keyframe = new Ext.fx.Animator({ target: dom, 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() { var el = Ext.fly(dom, '_anim'); if (obj.useDisplay) { el.setDisplayed(false); } else { el.hide(); } el.clearOpacity(); el.setPositioning(position); el.setSize(size); animScope.end(); }); }; me.animate({ duration: (Math.max(obj.duration, 500) * 2), listeners: { beforeanimate: { fn: beforeAnim } }, callback: obj.callback, scope: obj.scope }); return me; }, syncContent: function(source) { source = Ext.getDom(source); var sourceNodes = source.childNodes, sourceLen = sourceNodes.length, dest = this.dom, destNodes = dest.childNodes, destLen = destNodes.length, i, destNode, sourceNode, nodeType, newAttrs, attLen, attName, elData = dest._extData; if (Ext.isIE9m && dest.mergeAttributes) { dest.mergeAttributes(source, true); dest.src = source.src; } else { newAttrs = source.attributes; attLen = newAttrs.length; for (i = 0; i < attLen; i++) { attName = newAttrs[i].name; if (attName !== 'id') { dest.setAttribute(attName, newAttrs[i].value); } } } if (elData) { elData.isSynchronized = false; } if (sourceLen !== destLen) { dest.innerHTML = source.innerHTML; return; } for (i = 0; i < sourceLen; i++) { sourceNode = sourceNodes[i]; destNode = destNodes[i]; nodeType = sourceNode.nodeType; if (nodeType !== destNode.nodeType || (nodeType === 1 && sourceNode.tagName !== destNode.tagName)) { dest.innerHTML = source.innerHTML; return; } if (nodeType === 3) { destNode.data = sourceNode.data; } else { if (sourceNode.id && destNode.id !== sourceNode.id) { destNode.id = sourceNode.id; } destNode.style.cssText = sourceNode.style.cssText; destNode.className = sourceNode.className; Ext.fly(destNode, '_syncContent').syncContent(sourceNode); } } }, toggle: function(animate) { var me = this; me.setVisible(!me.isVisible(), me.anim(animate)); return me; }, unmask: function() { var me = this, data = me.getData(), maskEl = data.maskEl, style; if (maskEl) { style = maskEl.dom.style; if (style.clearExpression) { style.clearExpression('width'); style.clearExpression('height'); } if (maskEl) { maskEl.destroy(); delete data.maskEl; } me.removeCls([ XMASKED, XMASKEDRELATIVE ]); } me.restoreChildrenTabbableState(); if (me.dom !== DOC.body) { me.restoreTabbableState(); } }, unclip: function() { var me = this, data = me.getData(), clip; if (data[ISCLIPPED]) { data[ISCLIPPED] = false; clip = data[ORIGINALCLIP]; if (clip.o) { me.setStyle(OVERFLOW, clip.o); } if (clip.x) { me.setStyle(OVERFLOWX, clip.x); } if (clip.y) { me.setStyle(OVERFLOWY, clip.y); } } return me; }, translate: function(x, y, z) { if (Ext.supports.CssTransforms && !Ext.isIE9m) { this.callParent(arguments); } else { if (x != null) { this.dom.style.left = x + 'px'; } if (y != null) { this.dom.style.top = y + 'px'; } } }, unselectable: function() { var me = this; if (Ext.isOpera) { me.dom.unselectable = 'on'; } me.removeCls(Element.selectableCls); me.addCls(Element.unselectableCls); return me; }, privates: { needsTabIndex: function() { var dom = this.dom, nodeName, isFocusable; if (dom) { nodeName = dom.nodeName; isFocusable = !!Ext.Element.naturallyFocusableTags[nodeName] || ((nodeName === 'A' || nodeName === 'LINK') && !!dom.href) || dom.getAttribute('tabindex') != null || dom.contentEditable === 'true'; return !isFocusable; } }, findTabbableElements: function(asDom, selector, limit, backward) { asDom = asDom != undefined ? asDom : true; var me = this, selection; selection = me.selectTabbableElements(asDom, selector, limit, backward); if (me.isTabbable()) { selection.unshift(asDom ? me.dom : me); } return selection; }, selectTabbableElements: function(asDom, selector, limit, backward) { var selection = [], nodes, node, el, i, len, to, step, tabIndex; asDom = asDom != undefined ? asDom : true; nodes = this.dom.querySelectorAll(selector || Ext.Element.tabbableSelector); len = nodes.length; if (!len) { return selection; } if (backward) { i = len - 1; to = 0; step = -1; } else { i = 0; to = len - 1; step = 1; } for (; ; i += step) { if ((step > 0 && i > to) || (step < 0 && i < to)) { break; } node = nodes[i]; tabIndex = node.getAttribute('tabindex') - 0; if (!(tabIndex < 0)) { el = asDom ? Ext.fly(node) : Ext.get(node); if (el.isTabbable()) { selection.push(asDom ? node : el); } } if (selection.length >= limit) { return selection; } } return selection; }, selectFirstTabbableElement: function(asDom, selector) { var els = this.selectTabbableElements(asDom, selector, 1, false); return els[0]; }, selectLastTabbableElement: function(asDom, selector) { var el = this.selectTabbableElements(true, selector, 1, true)[0]; return (asDom !== false) ? el : Ext.get(el); }, saveTabbableState: function(attribute) { var tabbableSavedFlagAttribute = Ext.Element.tabbableSavedFlagAttribute, dom = this.dom; if (dom.hasAttribute(tabbableSavedFlagAttribute)) { return; } attribute = attribute || Ext.Element.tabbableSavedAttribute; if (dom.hasAttribute('tabindex')) { dom.setAttribute(attribute, dom.getAttribute('tabindex')); } else { dom.setAttribute(attribute, 'none'); } dom.setAttribute('tabindex', -1); dom.setAttribute(tabbableSavedFlagAttribute, true); return this; }, restoreTabbableState: function(attribute) { var tabbableSavedFlagAttribute = Ext.Element.tabbableSavedFlagAttribute, dom = this.dom, idx; attribute = attribute || Ext.Element.tabbableSavedAttribute; if (!dom.hasAttribute(tabbableSavedFlagAttribute) || !dom.hasAttribute(attribute)) { return; } idx = dom.getAttribute(attribute); if (idx === 'none') { dom.removeAttribute('tabindex'); } else { dom.setAttribute('tabindex', idx); } dom.removeAttribute(attribute); dom.removeAttribute(tabbableSavedFlagAttribute); return this; }, saveChildrenTabbableState: function(attribute) { var children, child, i, len; if (this.dom) { children = this.selectTabbableElements(); for (i = 0 , len = children.length; i < len; i++) { child = Ext.fly(children[i]); child.saveTabbableState(attribute); } } return children; }, restoreChildrenTabbableState: function(attribute, children) { var child, i, len; if (this.dom) { attribute = attribute || Ext.Element.tabbableSavedAttribute; children = children || this.dom.querySelectorAll('[' + attribute + ']'); for (i = 0 , len = children.length; i < len; i++) { child = Ext.fly(children[i]); child.restoreTabbableState(attribute); } } return children; } }, deprecated: { '4.0': { methods: { pause: function(ms) { var me = this; Ext.fx.Manager.setFxDefaults(me.id, { delay: ms }); return me; }, scale: function(w, h, o) { this.animate(Ext.apply({}, o, { width: w, height: h })); return this; }, shift: function(config) { this.animate(config); return this; } } }, '4.2': { methods: { moveTo: function(x, y, animate) { return this.setXY([ x, y ], animate); }, setBounds: function(x, y, width, height, animate) { return this.setBox({ x: x, y: y, width: width, height: height }, animate); }, setLeftTop: function(left, top) { var me = this, style = me.dom.style; style.left = Element.addUnits(left); style.top = Element.addUnits(top); if (me.shadow || me.shim) { me.syncUnderlays(); } return me; }, setLocation: function(x, y, animate) { return this.setXY([ x, y ], animate); } } }, '5.0': { methods: { getAttributeNS: function(namespace, name) { return this.getAttribute(name, namespace); }, getCenterXY: function() { return this.getAlignToXY(DOC, 'c-c'); }, getComputedHeight: function() { return Math.max(this.dom.offsetHeight, this.dom.clientHeight) || parseFloat(this.getStyle(HEIGHT)) || 0; }, getComputedWidth: function() { return Math.max(this.dom.offsetWidth, this.dom.clientWidth) || parseFloat(this.getStyle(WIDTH)) || 0; }, getStyleSize: function() { var me = this, d = this.dom, isDoc = (d === DOC || d === DOC.body), s, w, h; if (isDoc) { return { width: Element.getViewportWidth(), height: Element.getViewportHeight() }; } s = me.getStyle([ 'height', 'width' ], true); if (s.width && s.width !== 'auto') { w = parseFloat(s.width); } if (s.height && s.height !== 'auto') { h = parseFloat(s.height); } return { width: w || me.getWidth(true), height: h || me.getHeight(true) }; }, isBorderBox: function() { return true; }, isDisplayed: function() { return !this.isStyle('display', 'none'); }, focusable: 'isFocusable' } } } }; })(), function() { var Element = Ext.dom.Element, proto = Element.prototype, useDocForId = !Ext.isIE8, DOC = document, view = DOC.defaultView, opacityRe = /alpha\(opacity=(.*)\)/i, trimRe = /^\s+|\s+$/g, styleHooks = proto.styleHooks, supports = Ext.supports, verticalStyleHooks90, verticalStyleHooks270, edges, k, edge, borderWidth, getBorderWidth; proto._init(Element); delete proto._init; Ext.plainTableCls = Ext.baseCSSPrefix + 'table-plain'; Ext.plainListCls = Ext.baseCSSPrefix + 'list-plain'; if (Ext.CompositeElementLite) { Ext.CompositeElementLite.importElementMethods(); } styleHooks.opacity = { name: 'opacity', afterSet: function(dom, value, el) { var shadow = el.shadow; if (shadow) { shadow.setOpacity(value); } } }; if (!supports.Opacity && Ext.isIE) { Ext.apply(styleHooks.opacity, { get: function(dom) { var filter = dom.style.filter, match, opacity; if (filter.match) { match = filter.match(opacityRe); if (match) { opacity = parseFloat(match[1]); if (!isNaN(opacity)) { return opacity ? opacity / 100 : 0; } } } return 1; }, set: function(dom, value) { var style = dom.style, val = style.filter.replace(opacityRe, '').replace(trimRe, ''); style.zoom = 1; if (typeof (value) === 'number' && value >= 0 && value < 1) { value *= 100; style.filter = val + (val.length ? ' ' : '') + 'alpha(opacity=' + value + ')'; } else { style.filter = val; } } }); } if (!supports.matchesSelector) { var simpleSelectorRe = /^([a-z]+|\*)?(?:\.([a-z][a-z\-_0-9]*))?$/i, dashRe = /\-/g, fragment, classMatcher = function(tag, cls) { var classRe = new RegExp('(?:^|\\s+)' + cls.replace(dashRe, '\\-') + '(?:\\s+|$)'); if (tag && tag !== '*') { tag = tag.toUpperCase(); return function(el) { return el.tagName === tag && classRe.test(el.className); }; } return function(el) { return classRe.test(el.className); }; }, tagMatcher = function(tag) { tag = tag.toUpperCase(); return function(el) { return el.tagName === tag; }; }, cache = {}; proto.matcherCache = cache; proto.is = function(selector) { if (!selector) { return true; } var dom = this.dom, cls, match, testFn, root, isOrphan, is, tag; if (dom.nodeType !== 1) { return false; } if (!(testFn = Ext.isFunction(selector) ? selector : cache[selector])) { if (!(match = selector.match(simpleSelectorRe))) { root = dom.parentNode; if (!root) { isOrphan = true; root = fragment || (fragment = DOC.createDocumentFragment()); fragment.appendChild(dom); } is = Ext.Array.indexOf(Ext.fly(root, '_is').query(selector), dom) !== -1; if (isOrphan) { fragment.removeChild(dom); } return is; } tag = match[1]; cls = match[2]; cache[selector] = testFn = cls ? classMatcher(tag, cls) : tagMatcher(tag); } return testFn(dom); }; } if (!view || !view.getComputedStyle) { proto.getStyle = function(property, inline) { var me = this, dom = me.dom, multiple = typeof property !== 'string', prop = property, props = prop, len = 1, isInline = inline, styleHooks = me.styleHooks, camel, domStyle, values, hook, out, style, i; if (multiple) { values = {}; prop = props[0]; i = 0; if (!(len = props.length)) { return values; } } if (!dom || dom.documentElement) { return values || ''; } domStyle = dom.style; if (inline) { style = domStyle; } else { style = dom.currentStyle; if (!style) { isInline = true; style = domStyle; } } do { hook = styleHooks[prop]; if (!hook) { styleHooks[prop] = hook = { name: Element.normalize(prop) }; } if (hook.get) { out = hook.get(dom, me, isInline, style); } else { camel = hook.name; out = style[camel]; } if (!multiple) { return out; } values[prop] = out; prop = props[++i]; } while (i < len); return values; }; } if (Ext.isIE8) { getBorderWidth = function(dom, el, inline, style) { if (style[this.styleName] === 'none') { return '0px'; } return style[this.name]; }; edges = [ 'Top', 'Right', 'Bottom', 'Left' ]; k = edges.length; while (k--) { edge = edges[k]; borderWidth = 'border' + edge + 'Width'; styleHooks['border-' + edge.toLowerCase() + '-width'] = styleHooks[borderWidth] = { name: borderWidth, styleName: 'border' + edge + 'Style', get: getBorderWidth }; } } Ext.apply(Ext, { enableGarbageCollector: true, isBorderBox: true, useShims: false, getDetachedBody: function() { var detachedEl = Ext.detachedBodyEl; if (!detachedEl) { detachedEl = DOC.createElement('div'); Ext.detachedBodyEl = detachedEl = new Ext.dom.Fly(detachedEl); detachedEl.isDetachedBody = true; } return detachedEl; }, getElementById: function(id) { var el = DOC.getElementById(id), detachedBodyEl; if (!el && (detachedBodyEl = Ext.detachedBodyEl)) { el = detachedBodyEl.dom.querySelector(Ext.makeIdSelector(id)); } return el; }, addBehaviors: function(o) { if (!Ext.isReady) { Ext.onInternalReady(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.fly(document).select(s, true); } cache[s].on(parts[1], o[b]); } } cache = null; } } }); if (Ext.isIE9m) { Ext.getElementById = function(id) { var el = DOC.getElementById(id), detachedBodyEl; if (!el && (detachedBodyEl = Ext.detachedBodyEl)) { el = detachedBodyEl.dom.all[id]; } return el; }; proto.getById = function(id, asDom) { var dom = this.dom, ret = null, entry, el; if (dom) { el = (useDocForId && DOC.getElementById(id)) || dom.all[id]; if (el) { if (asDom) { ret = el; } else { entry = Ext.cache[id]; if (entry) { if (entry.skipGarbageCollection || !Ext.isGarbage(entry.dom)) { ret = entry; } else { Ext.Error.raise("Stale Element with id '" + el.id + "' found in Element cache. " + "Make sure to clean up Element instances using destroy()"); entry.destroy(); } } ret = ret || new Ext.Element(el); } } } return ret; }; } else if (!DOC.querySelector) { Ext.getDetachedBody = Ext.getBody; Ext.getElementById = function(id) { return DOC.getElementById(id); }; proto.getById = function(id, asDom) { var dom = DOC.getElementById(id); return asDom ? dom : (dom ? Ext.get(dom) : null); }; } if (Ext.isIE && !(Ext.isIE9p && DOC.documentMode >= 9)) { proto.getAttribute = 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; }; } Ext.onInternalReady(function() { var transparentRe = /^(?:transparent|(?:rgba[(](?:\s*\d+\s*[,]){3}\s*0\s*[)]))$/i, bodyCls = [], origSetWidth = proto.setWidth, origSetHeight = proto.setHeight, origSetSize = proto.setSize, pxRe = /^\d+(?:\.\d*)?px$/i, colorStyles, i, name, camel; if (supports.FixedTableWidthBug) { styleHooks.width = { name: 'width', set: function(dom, value, el) { var style = dom.style, needsFix = el._needsTableWidthFix, origDisplay = style.display; if (needsFix) { style.display = 'none'; } style.width = value; if (needsFix) { dom.scrollWidth; style.display = origDisplay; } } }; proto.setWidth = function(width, animate) { var me = this, dom = me.dom, style = dom.style, needsFix = me._needsTableWidthFix, origDisplay = style.display; if (needsFix && !animate) { style.display = 'none'; } origSetWidth.call(me, width, animate); if (needsFix && !animate) { dom.scrollWidth; style.display = origDisplay; } return me; }; proto.setSize = function(width, height, animate) { var me = this, dom = me.dom, style = dom.style, needsFix = me._needsTableWidthFix, origDisplay = style.display; if (needsFix && !animate) { style.display = 'none'; } origSetSize.call(me, width, height, animate); if (needsFix && !animate) { dom.scrollWidth; style.display = origDisplay; } return me; }; } if (Ext.isIE8) { styleHooks.height = { name: 'height', set: function(dom, value, el) { var component = el.component, frameInfo, frameBodyStyle; if (component && component._syncFrameHeight && this === component.el) { frameBodyStyle = component.frameBody.dom.style; if (pxRe.test(value)) { frameInfo = component.getFrameInfo(); if (frameInfo) { frameBodyStyle.height = (parseInt(value, 10) - frameInfo.height) + 'px'; } } else if (!value || value === 'auto') { frameBodyStyle.height = ''; } } dom.style.height = value; } }; proto.setHeight = function(height, animate) { var component = this.component, frameInfo, frameBodyStyle; if (component && component._syncFrameHeight && this === component.el) { frameBodyStyle = component.frameBody.dom.style; if (!height || height === 'auto') { frameBodyStyle.height = ''; } else { frameInfo = component.getFrameInfo(); if (frameInfo) { frameBodyStyle.height = (height - frameInfo.height) + 'px'; } } } return origSetHeight.call(this, height, animate); }; proto.setSize = function(width, height, animate) { var component = this.component, frameInfo, frameBodyStyle; if (component && component._syncFrameHeight && this === component.el) { frameBodyStyle = component.frameBody.dom.style; if (!height || height === 'auto') { frameBodyStyle.height = ''; } else { frameInfo = component.getFrameInfo(); if (frameInfo) { frameBodyStyle.height = (height - frameInfo.height) + 'px'; } } } return origSetSize.call(this, width, height, animate); }; } Ext.getDoc().on('selectstart', function(ev, dom) { var selectableCls = Element.selectableCls, unselectableCls = Element.unselectableCls, tagName = dom && dom.tagName; tagName = tagName && tagName.toLowerCase(); if (tagName === 'input' || tagName === 'textarea') { return; } while (dom && dom.nodeType === 1 && dom !== DOC.documentElement) { var el = Ext.fly(dom); if (el.hasCls(selectableCls)) { return; } if (el.hasCls(unselectableCls)) { ev.stopEvent(); return; } dom = dom.parentNode; } }); function fixTransparent(dom, el, inline, style) { var value = style[this.name] || ''; return transparentRe.test(value) ? 'transparent' : value; } function makeSelectionRestoreFn(activeEl, start, end) { return function() { activeEl.selectionStart = start; activeEl.selectionEnd = end; }; } function getRightMarginFixCleaner(target) { var hasInputBug = supports.DisplayChangeInputSelectionBug, hasTextAreaBug = supports.DisplayChangeTextAreaSelectionBug, activeEl, tag, start, end; if (hasInputBug || hasTextAreaBug) { activeEl = Element.getActiveElement(); tag = activeEl && activeEl.tagName; if ((hasTextAreaBug && tag === 'TEXTAREA') || (hasInputBug && tag === 'INPUT' && activeEl.type === 'text')) { if (Ext.fly(target).isAncestor(activeEl)) { start = activeEl.selectionStart; end = activeEl.selectionEnd; if (Ext.isNumber(start) && Ext.isNumber(end)) { return makeSelectionRestoreFn(activeEl, start, end); } } } } return Ext.emptyFn; } function fixRightMargin(dom, el, inline, style) { var result = style.marginRight, domStyle, display; if (result !== '0px') { domStyle = dom.style; display = domStyle.display; domStyle.display = 'inline-block'; result = (inline ? style : dom.ownerDocument.defaultView.getComputedStyle(dom, null)).marginRight; domStyle.display = display; } return result; } function fixRightMarginAndInputFocus(dom, el, inline, style) { var result = style.marginRight, domStyle, cleaner, display; if (result !== '0px') { domStyle = dom.style; cleaner = getRightMarginFixCleaner(dom); display = domStyle.display; domStyle.display = 'inline-block'; result = (inline ? style : dom.ownerDocument.defaultView.getComputedStyle(dom, '')).marginRight; domStyle.display = display; cleaner(); } return result; } if (!supports.RightMargin) { styleHooks.marginRight = styleHooks['margin-right'] = { name: 'marginRight', get: (supports.DisplayChangeInputSelectionBug || supports.DisplayChangeTextAreaSelectionBug) ? fixRightMarginAndInputFocus : fixRightMargin }; } if (!supports.TransparentColor) { colorStyles = [ 'background-color', 'border-color', 'color', 'outline-color' ]; for (i = colorStyles.length; i--; ) { name = colorStyles[i]; camel = Element.normalize(name); styleHooks[name] = styleHooks[camel] = { name: camel, get: fixTransparent }; } } proto.verticalStyleHooks90 = verticalStyleHooks90 = Ext.Object.chain(styleHooks); proto.verticalStyleHooks270 = verticalStyleHooks270 = Ext.Object.chain(styleHooks); verticalStyleHooks90.width = styleHooks.height || { name: 'height' }; verticalStyleHooks90.height = styleHooks.width || { name: 'width' }; verticalStyleHooks90['margin-top'] = { name: 'marginLeft' }; verticalStyleHooks90['margin-right'] = { name: 'marginTop' }; verticalStyleHooks90['margin-bottom'] = { name: 'marginRight' }; verticalStyleHooks90['margin-left'] = { name: 'marginBottom' }; verticalStyleHooks90['padding-top'] = { name: 'paddingLeft' }; verticalStyleHooks90['padding-right'] = { name: 'paddingTop' }; verticalStyleHooks90['padding-bottom'] = { name: 'paddingRight' }; verticalStyleHooks90['padding-left'] = { name: 'paddingBottom' }; verticalStyleHooks90['border-top'] = { name: 'borderLeft' }; verticalStyleHooks90['border-right'] = { name: 'borderTop' }; verticalStyleHooks90['border-bottom'] = { name: 'borderRight' }; verticalStyleHooks90['border-left'] = { name: 'borderBottom' }; verticalStyleHooks270.width = styleHooks.height || { name: 'height' }; verticalStyleHooks270.height = styleHooks.width || { name: 'width' }; verticalStyleHooks270['margin-top'] = { name: 'marginRight' }; verticalStyleHooks270['margin-right'] = { name: 'marginBottom' }; verticalStyleHooks270['margin-bottom'] = { name: 'marginLeft' }; verticalStyleHooks270['margin-left'] = { name: 'marginTop' }; verticalStyleHooks270['padding-top'] = { name: 'paddingRight' }; verticalStyleHooks270['padding-right'] = { name: 'paddingBottom' }; verticalStyleHooks270['padding-bottom'] = { name: 'paddingLeft' }; verticalStyleHooks270['padding-left'] = { name: 'paddingTop' }; verticalStyleHooks270['border-top'] = { name: 'borderRight' }; verticalStyleHooks270['border-right'] = { name: 'borderBottom' }; verticalStyleHooks270['border-bottom'] = { name: 'borderLeft' }; verticalStyleHooks270['border-left'] = { name: 'borderTop' }; if (!Ext.scopeCss) { bodyCls.push(Ext.baseCSSPrefix + 'body'); } if (supports.Touch) { bodyCls.push(Ext.baseCSSPrefix + 'touch'); } if (Ext.isIE && Ext.isIE9m) { bodyCls.push(Ext.baseCSSPrefix + 'ie', Ext.baseCSSPrefix + 'ie9m'); bodyCls.push(Ext.baseCSSPrefix + 'ie8p'); if (Ext.isIE8) { bodyCls.push(Ext.baseCSSPrefix + 'ie8'); } else { bodyCls.push(Ext.baseCSSPrefix + 'ie9', Ext.baseCSSPrefix + 'ie9p'); } if (Ext.isIE8m) { bodyCls.push(Ext.baseCSSPrefix + 'ie8m'); } } if (Ext.isIE10) { bodyCls.push(Ext.baseCSSPrefix + 'ie10'); } if (Ext.isIE11) { bodyCls.push(Ext.baseCSSPrefix + 'ie11'); } if (Ext.isGecko) { bodyCls.push(Ext.baseCSSPrefix + 'gecko'); } if (Ext.isOpera) { bodyCls.push(Ext.baseCSSPrefix + 'opera'); } if (Ext.isOpera12m) { bodyCls.push(Ext.baseCSSPrefix + 'opera12m'); } if (Ext.isWebKit) { bodyCls.push(Ext.baseCSSPrefix + 'webkit'); } if (Ext.isSafari) { bodyCls.push(Ext.baseCSSPrefix + 'safari'); } if (Ext.isChrome) { bodyCls.push(Ext.baseCSSPrefix + 'chrome'); } if (Ext.isMac) { bodyCls.push(Ext.baseCSSPrefix + 'mac'); } if (Ext.isLinux) { bodyCls.push(Ext.baseCSSPrefix + 'linux'); } if (!supports.CSS3BorderRadius) { bodyCls.push(Ext.baseCSSPrefix + 'nbr'); } if (!supports.CSS3LinearGradient) { bodyCls.push(Ext.baseCSSPrefix + 'nlg'); } if (supports.Touch) { bodyCls.push(Ext.baseCSSPrefix + 'touch'); } Ext.getBody().addCls(bodyCls); }, null, { priority: 1500 }); }); Ext.define('Ext.GlobalEvents', { extend: 'Ext.mixin.Observable', alternateClassName: 'Ext.globalEvents', requires: [ 'Ext.dom.Element' ], observableType: 'global', singleton: true, resizeBuffer: 100, idleEventMask: { mousemove: 1, touchmove: 1, pointermove: 1, MSPointerMove: 1, unload: 1 }, constructor: function() { var me = this; me.callParent(); Ext.onInternalReady(function() { me.attachListeners(); }); }, attachListeners: function() { Ext.get(window).on('resize', this.fireResize, this, { buffer: this.resizeBuffer }); }, fireResize: function() { var me = this, Element = Ext.Element, w = Element.getViewportWidth(), h = Element.getViewportHeight(); if (me.curHeight !== h || me.curWidth !== w) { me.curHeight = h; me.curWidth = w; me.fireEvent('resize', w, h); } } }, function(GlobalEvents) { Ext.on = function() { return GlobalEvents.addListener.apply(GlobalEvents, arguments); }; Ext.un = function() { return GlobalEvents.removeListener.apply(GlobalEvents, arguments); }; }); Ext.define('Ext.overrides.GlobalEvents', { override: 'Ext.GlobalEvents', attachListeners: function() { this.callParent(); Ext.getDoc().on('mousedown', this.fireMouseDown, this); }, fireMouseDown: function(e) { this.fireEvent('mousedown', e); }, deprecated: { 5: { methods: { addListener: function(ename, fn, scope, options, order, caller, eventOptions) { var name, readyFn; if (ename === 'ready') { readyFn = fn; } else if (typeof ename !== 'string') { for (name in ename) { if (name === 'ready') { readyFn = ename[name]; } } } if (readyFn) { Ext.log.warn("Ext.on('ready', fn) is deprecated. Please use Ext.onReady(fn) instead."); Ext.onReady(readyFn); } this.callParent([ ename, fn, scope, options, order, caller, eventOptions ]); } } } } }); Ext.USE_NATIVE_JSON = false; Ext.JSON = (new (function() { var me = this, hasNative = window.JSON && JSON.toString() === '[object JSON]', useHasOwn = !!{}.hasOwnProperty, pad = function(n) { return n < 10 ? "0" + n : n; }, doDecode = function(json) { return eval("(" + json + ')'); }, doEncode = function(o, newline) { if (o === null || o === undefined) { return "null"; } else if (Ext.isDate(o)) { return me.encodeDate(o); } else if (Ext.isString(o)) { if (Ext.isMSDate(o)) { return me.encodeMSDate(o); } else { return me.encodeString(o); } } else if (typeof o === "number") { return isFinite(o) ? String(o) : "null"; } else if (Ext.isBoolean(o)) { return String(o); } else if (o.toJSON) { return o.toJSON(); } else if (Ext.isArray(o)) { return encodeArray(o, newline); } else if (Ext.isObject(o)) { return encodeObject(o, newline); } else if (typeof o === "function") { return "null"; } return 'undefined'; }, m = { "\b": '\\b', "\t": '\\t', "\n": '\\n', "\f": '\\f', "\r": '\\r', '"': '\\"', "\\": '\\\\', '\v': '\\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); }) + '"'; }, encodeMSDate = function(o) { return '"' + o + '"'; }, encodeArrayPretty = function(o, newline) { var len = o.length, cnewline = newline + ' ', sep = ',' + cnewline, a = [ "[", cnewline ], i; for (i = 0; i < len; i += 1) { a.push(me.encodeValue(o[i], cnewline), sep); } a[a.length - 1] = newline + ']'; return a.join(''); }, encodeObjectPretty = function(o, newline) { var cnewline = newline + ' ', sep = ',' + cnewline, a = [ "{", cnewline ], i, val; for (i in o) { val = o[i]; if (!useHasOwn || o.hasOwnProperty(i)) { if (typeof val === 'function' || val === undefined) { continue; } a.push(me.encodeValue(i) + ': ' + me.encodeValue(val, cnewline), sep); } } a[a.length - 1] = newline + '}'; return a.join(''); }, encodeArray = function(o, newline) { if (newline) { return encodeArrayPretty(o, newline); } var a = [ "[", "" ], len = o.length, i; for (i = 0; i < len; i += 1) { a.push(me.encodeValue(o[i]), ','); } a[a.length - 1] = ']'; return a.join(""); }, encodeObject = function(o, newline) { if (newline) { return encodeObjectPretty(o, newline); } var a = [ "{", "" ], i, val; for (i in o) { val = o[i]; if (!useHasOwn || o.hasOwnProperty(i)) { if (typeof val === 'function' || val === undefined) { continue; } a.push(me.encodeValue(i), ":", me.encodeValue(val), ','); } } a[a.length - 1] = '}'; return a.join(""); }; me.encodeString = encodeString; me.encodeValue = doEncode; me.encodeDate = function(o) { return '"' + o.getFullYear() + "-" + pad(o.getMonth() + 1) + "-" + pad(o.getDate()) + "T" + pad(o.getHours()) + ":" + pad(o.getMinutes()) + ":" + pad(o.getSeconds()) + '"'; }; me.encode = function(o) { if (hasNative && Ext.USE_NATIVE_JSON) { return JSON.stringify(o); } return me.encodeValue(o); }; me.decode = function(json, safe) { try { if (hasNative && Ext.USE_NATIVE_JSON) { return JSON.parse(json); } return doDecode(json); } catch (e) { if (safe) { return null; } Ext.Error.raise({ sourceClass: "Ext.JSON", sourceMethod: "decode", msg: "You're trying to decode an invalid JSON String: " + json }); } }; me.encodeMSDate = encodeMSDate; //@private Alias for backwards compatibility if (!Ext.util) { Ext.util = {}; } Ext.util.JSON = me; Ext.encode = me.encode; Ext.decode = me.decode; })()); Ext.define('Ext.util.Format', function() { var me; return { requires: [ 'Ext.Error', 'Ext.Number', 'Ext.String', 'Ext.Date' ], singleton: true, defaultDateFormat: 'm/d/Y', thousandSeparator: ',', decimalSeparator: '.', currencyPrecision: 2, currencySign: '$', percentSign: '%', currencyAtEnd: false, stripTagsRe: /<\/?[^>]+>/gi, stripScriptsRe: /(?:)((\n|\r|.)*?)(?:<\/script>)/ig, nl2brRe: /\r?\n/g, hashRe: /#+$/, allHashes: /^#+$/, formatPattern: /[\d,\.#]+/, formatCleanRe: /[^\d\.#]/g, I18NFormatCleanRe: null, formatFns: {}, constructor: function() { me = this; }, undef: function(value) { return value !== undefined ? value : ""; }, defaultValue: function(value, defaultValue) { return value !== undefined && value !== '' ? value : defaultValue; }, substr: 'ab'.substr(-1) != 'b' ? function(value, start, length) { var str = String(value); return (start < 0) ? str.substr(Math.max(str.length + start, 0), length) : str.substr(start, length); } : 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 me.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 = Ext.isDefined(decimals) ? decimals : me.currencyPrecision; format += (decimals > 0 ? '.' : ''); for (; i < decimals; i++) { format += '0'; } v = me.number(v, format); if ((end || me.currencyAtEnd) === true) { return Ext.String.format("{0}{1}{2}", negativeSign, v, currencySign || me.currencySign); } else { return Ext.String.format("{0}{1}{2}", negativeSign, currencySign || me.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 me.date(v, format); }; }, hex: function(value, digits) { var s = parseInt(value || 0, 10).toString(16); if (digits) { if (digits < 0) { digits = -digits; if (s.length > digits) { s = s.substring(s.length - digits); } } while (s.length < digits) { s = '0' + s; } } return s; }, or: function(value, orValue) { return value || orValue; }, pick: function(value, firstValue, secondValue) { if (Ext.isNumber(value)) { var ret = arguments[value + 1]; if (ret) { return ret; } } return value ? secondValue : firstValue; }, stripTags: function(v) { return !v ? v : String(v).replace(me.stripTagsRe, ""); }, stripScripts: function(v) { return !v ? v : String(v).replace(me.stripScriptsRe, ""); }, fileSize: (function() { var byteLimit = 1024, kbLimit = 1048576, mbLimit = 1073741824; return function(size) { var out; if (size < byteLimit) { if (size === 1) { out = '1 byte'; } else { out = size + ' bytes'; } } else if (size < kbLimit) { out = (Math.round(((size * 10) / byteLimit)) / 10) + ' KB'; } else if (size < mbLimit) { out = (Math.round(((size * 10) / kbLimit)) / 10) + ' MB'; } else { out = (Math.round(((size * 10) / mbLimit)) / 10) + ' GB'; } return out; }; })(), 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; } else if (precision === undefined) { result = Math.round(result); } return result; }, number: function(v, formatString) { if (!formatString) { return v; } if (isNaN(v)) { return ''; } var formatFn = me.formatFns[formatString]; if (!formatFn) { var originalFormatString = formatString, comma = me.thousandSeparator, decimalSeparator = me.decimalSeparator, precision = 0, trimPart = '', hasComma, splitFormat, extraChars, trimTrailingZeroes, code, len; if (formatString.substr(formatString.length - 2) === '/i') { if (!me.I18NFormatCleanRe || me.lastDecimalSeparator !== decimalSeparator) { me.I18NFormatCleanRe = new RegExp('[^\\d\\' + decimalSeparator + ']', 'g'); me.lastDecimalSeparator = decimalSeparator; } formatString = formatString.substr(0, formatString.length - 2); hasComma = formatString.indexOf(comma) !== -1; splitFormat = formatString.replace(me.I18NFormatCleanRe, '').split(decimalSeparator); } else { hasComma = formatString.indexOf(',') !== -1; splitFormat = formatString.replace(me.formatCleanRe, '').split('.'); } extraChars = formatString.replace(me.formatPattern, ''); if (splitFormat.length > 2) { 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 if (splitFormat.length === 2) { precision = splitFormat[1].length; trimTrailingZeroes = splitFormat[1].match(me.hashRe); if (trimTrailingZeroes) { len = trimTrailingZeroes[0].length; trimPart = 'trailingZeroes=new RegExp(Ext.String.escapeRegex(utilFormat.decimalSeparator) + "*0{0,' + len + '}$")'; } } code = [ 'var utilFormat=Ext.util.Format,extNumber=Ext.Number,neg,absVal,fnum,parts' + (hasComma ? ',thousandSeparator,thousands=[],j,n,i' : '') + (extraChars ? ',formatString="' + formatString + '",formatPattern=/[\\d,\\.#]+/' : '') + ',trailingZeroes;' + 'return function(v){' + 'if(typeof v!=="number"&&isNaN(v=extNumber.from(v,NaN)))return"";' + 'neg=v<0;', 'absVal=Math.abs(v);', 'fnum=Ext.Number.toFixed(absVal, ' + precision + ');', trimPart, ';' ]; if (hasComma) { if (precision) { code[code.length] = 'parts=fnum.split(".");'; code[code.length] = 'fnum=parts[0];'; } code[code.length] = 'if(absVal>=1000) {'; code[code.length] = 'thousandSeparator=utilFormat.thousandSeparator;' + 'thousands.length=0;' + 'j=fnum.length;' + 'n=fnum.length%3||3;' + 'for(i=0;i'); }, capitalize: Ext.String.capitalize, uncapitalize: Ext.String.uncapitalize, ellipsis: Ext.String.ellipsis, escape: Ext.String.escape, escapeRegex: Ext.String.escapeRegex, htmlDecode: Ext.String.htmlDecode, htmlEncode: Ext.String.htmlEncode, leftPad: Ext.String.leftPad, toggle: Ext.String.toggle, trim: Ext.String.trim, parseBox: function(box) { box = box || 0; if (typeof box === 'number') { return { top: box, right: box, bottom: box, left: box }; } 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 }; } }; }); Ext.define('Ext.Template', { requires: [ 'Ext.util.Format' ], inheritableStatics: { from: function(el, config) { el = Ext.getDom(el); return new this(el.value || el.innerHTML, config || ''); } }, useEval: Ext.isGecko, constructor: function(html) { var me = this, args = arguments, buffer = [], i, length = args.length, value; me.initialConfig = {}; if (length === 1 && Ext.isArray(html)) { args = html; length = args.length; } if (length > 1) { for (i = 0; i < length; i++) { value = args[i]; if (typeof value === 'object') { Ext.apply(me.initialConfig, value); Ext.apply(me, value); } else { buffer.push(value); } } } else { buffer.push(html); } me.html = buffer.join(''); }, isTemplate: true, disableFormats: false, tokenRe: /\{(?:(?:(\d+)|([a-z_][\w\-]*))(?::([a-z_\.]+)(?:\(([^\)]*?)?\))?)?)\}/gi, apply: function(values) { var me = this; if (me.compiled) { if (!me.fn) { me.compile(); } return me.fn(values).join(''); } return me.evaluate(values); }, evaluate: function(values) { var me = this, useFormat = !me.disableFormats, fm = Ext.util.Format, tpl = me; function fn(match, index, name, formatFn, args) { if (name == null || name === '') { name = index; } if (formatFn && useFormat) { if (args) { args = [ values[name] ].concat(Ext.functionFactory('return [' + args + '];')()); } else { args = [ values[name] ]; } if (formatFn.substr(0, 5) === "this.") { return tpl[formatFn.substr(5)].apply(tpl, args); } else if (fm[formatFn]) { return fm[formatFn].apply(fm, args); } else { return match; } } else { return values[name] !== undefined ? values[name] : ""; } } return me.html.replace(me.tokenRe, fn); }, applyOut: function(values, out) { var me = this; if (me.compiled) { if (!me.fn) { me.compile(); } out.push.apply(out, me.fn(values)); } else { out.push(me.apply(values)); } return out; }, applyTemplate: function() { return this.apply.apply(this, arguments); }, set: function(html, compile) { var me = this; me.html = html; me.compiled = !!compile; me.fn = null; return me; }, compileARe: /\\/g, compileBRe: /(\r\n|\n)/g, compileCRe: /'/g, compile: function() { var me = this, code; code = me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.tokenRe, me.regexReplaceFn.bind(me)); code = (this.disableFormats !== true ? 'var fm=Ext.util.Format;' : '') + (me.useEval ? '$=' : 'return') + " function(v){return ['" + code + "'];};"; me.fn = me.useEval ? me.evalCompiled(code) : (new Function('Ext', code))(Ext); me.compiled = true; return me; }, evalCompiled: function($) { eval($); return $; }, regexReplaceFn: function(match, index, name, formatFn, args) { if (index == null || index === '') { index = '"' + name + '"'; } else if (this.stringFormat) { index = parseInt(index) + 1; } if (formatFn && this.disableFormats !== true) { args = args ? ',' + args : ""; if (formatFn.substr(0, 5) === "this.") { formatFn = formatFn + '('; } else if (Ext.util.Format[formatFn]) { formatFn = "fm." + formatFn + '('; } else { return match; } return "'," + formatFn + "v[" + index + "]" + args + "),'"; } else { return "',v[" + index + "] == undefined ? '' : v[" + index + "],'"; } }, insertFirst: function(el, values, returnElement) { return this.doInsert('afterBegin', el, values, returnElement); }, insertBefore: function(el, values, returnElement) { return this.doInsert('beforeBegin', el, values, returnElement); }, insertAfter: function(el, values, returnElement) { return this.doInsert('afterEnd', el, values, returnElement); }, append: function(el, values, returnElement) { return this.doInsert('beforeEnd', el, values, returnElement); }, doInsert: function(where, el, values, returnElement) { var newNode = Ext.DomHelper.insertHtml(where, Ext.getDom(el), this.apply(values)); return returnElement ? Ext.get(newNode) : newNode; }, overwrite: function(el, values, returnElement) { var newNode = Ext.DomHelper.overwrite(Ext.getDom(el), this.apply(values)); return returnElement ? Ext.get(newNode) : newNode; } }, function(Template) { var formatRe = /\{\d+\}/, generateFormatFn = function(format) { if (formatRe.test(format)) { format = new Template(format, formatTplConfig); return function() { return format.apply(arguments); }; } else { return function() { return format; }; } }, formatTplConfig = { useFormat: false, compiled: true, stringFormat: true }, formatFns = {}; Ext.String.format = Ext.util.Format.format = function(format) { var formatFn = formatFns[format] || (formatFns[format] = generateFormatFn(format)); return formatFn.apply(this, arguments); }; }); Ext.define('Ext.mixin.Inheritable', { extend: 'Ext.Mixin', mixinConfig: { id: 'inheritable' }, getInherited: function(inner) { var me = this, inheritedState = (inner && me.inheritedStateInner) || me.inheritedState, ownerCt = me.ownerCt || me.initOwnerCt, isContainer = me.isContainer, parent, inheritedStateInner, getInner; if (!inheritedState || inheritedState.invalid) { parent = me.getRefOwner(); if (ownerCt) { getInner = me.ownerLayout === ownerCt.layout; } me.inheritedState = inheritedState = Ext.Object.chain(parent ? parent.getInherited(getInner) : Ext.rootInheritedState); if (isContainer) { me.inheritedStateInner = inheritedStateInner = Ext.Object.chain(inheritedState); } me.initInheritedState(inheritedState, inheritedStateInner); inheritedState = (isContainer && inner) ? me.inheritedStateInner : me.inheritedState; } return inheritedState; }, getInheritedConfig: function(property, skipThis) { var state = this.inheritedState, old, ret; if (!state || state.invalid) { state = this.getInherited(); } ret = state[property]; if (skipThis && state.hasOwnProperty(property)) { old = ret; delete state[property]; ret = state[property]; state[property] = old; } return ret; }, fixReference: function() { var me = this, refHolder; if (me.reference) { refHolder = me.lookupReferenceHolder(); if (refHolder) { refHolder.attachReference(me); } } }, resolveListenerScope: function(defaultScope, skipThis) { var me = this, hasSkipThis = (typeof skipThis === 'boolean'), namedScope = Ext._namedScopes[defaultScope], ret; if (!namedScope) { ret = me.getInheritedConfig('defaultListenerScope', hasSkipThis ? skipThis : true) || defaultScope || me; } else if (namedScope.isController) { ret = me.getInheritedConfig('controller', hasSkipThis ? skipThis : !namedScope.isSelf); } else if (namedScope.isSelf) { ret = me.getInheritedConfig('defaultListenerScope', hasSkipThis && skipThis) || me; } else if (namedScope.isThis) { ret = me; } return ret || null; }, resolveSatelliteListenerScope: function(satellite, defaultScope) { var me = this, namedScope = Ext._namedScopes[defaultScope], ret; if (!namedScope) { ret = me.getInheritedConfig('defaultListenerScope') || defaultScope || me; } else if (namedScope.isController) { ret = me.getInheritedConfig('controller'); } else if (namedScope.isSelf) { ret = me.getInheritedConfig('defaultListenerScope') || satellite; } else if (namedScope.isThis) { ret = satellite; } return ret || null; }, lookupReferenceHolder: function(skipThis) { return this.getInheritedConfig('referenceHolder', skipThis !== false) || null; }, getRefOwner: function() { return this.ownerCt || this.initOwnerCt || this.ownerCmp || this.floatParent; }, invalidateInheritedState: function() { var inheritedState = this.inheritedState; if (inheritedState) { inheritedState.invalid = true; delete this.inheritedState; } } }, function() { Ext.rootInheritedState = {}; }); Ext.define('Ext.mixin.Bindable', { mixinId: 'bindable', config: { bind: { $value: null, lazy: true }, controller: null, defaultListenerScope: false, publishes: { $value: null, lazy: true, merge: function(newValue, oldValue) { return this.mergeSets(newValue, oldValue); } }, reference: null, session: { $value: null, lazy: true }, twoWayBindable: { $value: null, lazy: true, merge: function(newValue, oldValue) { return this.mergeSets(newValue, oldValue); } }, viewModel: { $value: null, lazy: true } }, defaultBindProperty: null, validRefRe: /^[a-z_][a-z0-9_]*$/i, initInheritedState: function(inheritedState) { var me = this, reference = me.getReference(), controller = me.getController(), viewModel = me.getConfig('viewModel', true), session = me.getConfig('session', true), defaultListenerScope = me.getDefaultListenerScope(); if (controller) { inheritedState.controller = controller; } if (defaultListenerScope) { inheritedState.defaultListenerScope = me; } else if (controller) { inheritedState.defaultListenerScope = controller; } if (viewModel) { if (!viewModel.isViewModel) { viewModel = me; } inheritedState.viewModel = viewModel; } if (session) { if (!session.isSession) { session = me; } inheritedState.session = session; } if (reference) { me.referenceKey = (inheritedState.referencePath || '') + reference; me.viewModelKey = (inheritedState.viewModelPath || '') + reference; } }, lookupController: function(skipThis) { return this.getInheritedConfig('controller', skipThis) || null; }, lookupSession: function(skipThis) { var ret = skipThis ? null : this.getSession(); if (!ret) { ret = this.getInheritedConfig('session', skipThis); if (ret && !ret.isSession) { ret = ret.getInherited().session = ret.getSession(); } } return ret || null; }, lookupViewModel: function(skipThis) { var ret = skipThis ? null : this.getViewModel(); if (!ret) { ret = this.getInheritedConfig('viewModel', skipThis); if (ret && !ret.isViewModel) { ret = ret.getInherited().viewModel = ret.getViewModel(); } } return ret || null; }, publishState: function(property, value) { var me = this, path = me.viewModelKey, state = me.publishedState, binds = me.getBind(), binding = binds && property && binds[property], count = 0, name, publishes, vm; if (binding && !binding.syncing && !binding.isReadOnly()) { if (!(binding.calls === 0 && (value == null || value === me.getInitialConfig()[property]))) { binding.setValue(value); } } if (!path || !(publishes = me.getPublishes())) { return; } if (!(vm = me.lookupViewModel())) { return; } if (property && state) { if (!publishes[property]) { return; } if (!(value && value.constructor === Object) && !(value instanceof Array)) { if (state[property] === value) { return; } } path += '.'; path += property; } else { state = state || (me.publishedState = {}); for (name in publishes) { ++count; if (name === property) { state[name] = value; } else { state[name] = me[name]; } } if (!count) { return; } value = state; } vm.set(path, value); }, privates: { addBindableUpdater: function(property) { var me = this, configs = me.self.$config.configs, cfg = configs[property], updateName; if (cfg && !me.hasOwnProperty(updateName = cfg.names.update)) { me[updateName] = cfg.bindableUpdater || (cfg.root.bindableUpdater = me.makeBindableUpdater(cfg)); } }, applyBind: function(binds, currentBindings) { var me = this, viewModel = me.lookupViewModel(), twoWayable = me.getTwoWayBindable(), getBindTemplateScope = me._getBindTemplateScope, b, property, descriptor; if (!currentBindings || typeof currentBindings === 'string') { currentBindings = {}; } if (!viewModel) { Ext.Error.raise('Cannot use bind config without a viewModel'); } if (Ext.isString(binds)) { if (!me.defaultBindProperty) { Ext.Error.raise(me.$className + ' has no defaultBindProperty - ' + 'Please specify a bind object'); } b = binds; binds = {}; binds[me.defaultBindProperty] = b; } for (property in binds) { descriptor = binds[property]; b = currentBindings[property]; if (b && typeof b !== 'string') { b.destroy(); b = null; } if (descriptor) { b = viewModel.bind(descriptor, me.onBindNotify, me); b._config = Ext.Config.get(property); b.getTemplateScope = getBindTemplateScope; if (!me[b._config.names.set]) { Ext.Error.raise('Cannot bind ' + property + ' on ' + me.$className + ' - missing a ' + b._config.names.set + ' method.'); } } currentBindings[property] = b; if (twoWayable && twoWayable[property] && !b.isReadOnly()) { me.addBindableUpdater(property); } } return currentBindings; }, applyController: function(controller) { if (controller) { controller = Ext.Factory.controller(controller); controller.setView(this); } return controller; }, applyPublishes: function(all) { if (this.lookupViewModel()) { for (var property in all) { this.addBindableUpdater(property); } } return all; }, applyReference: function(reference) { var validIdRe = this.validRefRe || Ext.validIdRe; if (reference && !validIdRe.test(reference)) { Ext.Error.raise('Invalid reference "' + reference + '" for ' + this.getId() + ' - not a valid identifier'); } return reference; }, applySession: function(session) { if (!session) { return null; } if (!session.isSession) { var parentSession = this.lookupSession(true), config = (session === true) ? {} : session; if (parentSession) { session = parentSession.spawn(config); } else { session = new Ext.data['Session'](config); } } return session; }, applyViewModel: function(viewModel) { var me = this, config, session; if (!(viewModel && viewModel.isViewModel)) { config = { parent: me.lookupViewModel(true) }; config.session = me.getSession(); if (!session && !config.parent) { config.session = me.lookupSession(); } if (viewModel) { if (viewModel.constructor === Object) { Ext.apply(config, viewModel); } else if (typeof viewModel === 'string') { config.type = viewModel; } } viewModel = Ext.Factory.viewModel(config); } return viewModel; }, _getBindTemplateScope: function() { return this.scope.resolveListenerScope(); }, initBindable: function() { this.initBindable = Ext.emptyFn; this.getBind(); this.getPublishes(); }, makeBindableUpdater: function(cfg) { var updateName = cfg.names.update; return function(newValue, oldValue) { var me = this, updater = me.self.prototype[updateName]; if (updater) { updater.call(me, newValue, oldValue); } me.publishState(cfg.name, newValue); }; }, onBindNotify: function(value, oldValue, binding) { binding.syncing = (binding.syncing + 1) || 1; this[binding._config.names.set](value); --binding.syncing; }, removeBindings: function() { var bindings = this.bind, key, binding; if (bindings && typeof bindings !== 'string') { for (key in bindings) { binding = bindings[key]; binding.destroy(); binding._config = binding.getTemplateScope = null; } } this.bind = null; }, updateSession: function(session) { var state = this.getInherited(); if (session) { state.session = session; } else { delete state.session; } }, updateViewModel: function(viewModel) { var state = this.getInherited(), controller = this.getController(); if (viewModel) { state.viewModel = viewModel; viewModel.setView(this); if (controller) { controller.initViewModel(viewModel); } } else { delete state.viewModel; } } } }); Ext.define('Ext.Widget', { extend: 'Ext.Evented', xtype: 'widget', requires: [ 'Ext.dom.Element' ], mixins: [ 'Ext.mixin.Inheritable', 'Ext.mixin.Bindable' ], isWidget: true, element: { reference: 'element' }, observableType: 'component', eventedConfig: { width: null, height: null }, template: [], constructor: function(config) { var me = this; me.initId(config); me.initElement(); me.mixins.observable.constructor.call(me, config); Ext.ComponentManager.register(me); }, afterCachedConfig: function() { var me = this, prototype = me.self.prototype, referenceList = me.referenceList, renderElement = me.renderElement.dom, renderTemplate, element, i, ln, reference, elements; prototype.renderTemplate = renderTemplate = document.createDocumentFragment(); renderTemplate.appendChild(renderElement.cloneNode(true)); elements = renderTemplate.querySelectorAll('[id]'); for (i = 0 , ln = elements.length; i < ln; i++) { element = elements[i]; element.removeAttribute('id'); } for (i = 0 , ln = referenceList.length; i < ln; i++) { reference = referenceList[i]; me[reference].dom.removeAttribute('reference'); } }, applyWidth: function(width) { return this.filterLengthValue(width); }, applyHeight: function(height) { return this.filterLengthValue(height); }, destroy: function() { var me = this, referenceList = me.referenceList, i, ln, reference; for (i = 0 , ln = referenceList.length; i < ln; i++) { reference = referenceList[i]; if (me.hasOwnProperty(reference)) { me[reference].destroy(); me[reference] = null; } } me.callParent(); Ext.ComponentManager.unregister(me); }, doSetWidth: function(width) { this.element.setWidth(width); }, doSetHeight: function(height) { this.element.setHeight(height); }, getElementConfig: function() { var me = this, el = me.element; if (!('children' in el)) { el = Ext.apply({ children: me.getTemplate() }, el); } return el; }, getItemId: function() { return this.itemId || this.id; }, getSize: function() { return { width: this.getWidth(), height: this.getHeight() }; }, getTemplate: function() { return this.template; }, initElement: function() { var me = this, prototype = me.self.prototype, id = me.getId(), referenceList = me.referenceList = [], cleanAttributes = true, renderTemplate, renderElement, element, referenceNodes, i, ln, referenceNode, reference; if (prototype.hasOwnProperty('renderTemplate')) { renderTemplate = me.renderTemplate.cloneNode(true); renderElement = renderTemplate.firstChild; } else { cleanAttributes = false; renderTemplate = document.createDocumentFragment(); renderElement = Ext.Element.create(me.processElementConfig.call(prototype), true); renderTemplate.appendChild(renderElement); } referenceNodes = renderTemplate.querySelectorAll('[reference]'); for (i = 0 , ln = referenceNodes.length; i < ln; i++) { referenceNode = referenceNodes[i]; reference = referenceNode.getAttribute('reference'); if (cleanAttributes) { referenceNode.removeAttribute('reference'); } if (reference === 'element') { if (element) { Ext.Error.raise("Duplicate 'element' reference detected in '" + me.$className + "' template."); } referenceNode.id = id; element = me.el = me.addElementReference(reference, referenceNode); } else { me.addElementReferenceOnDemand(reference, referenceNode); } referenceList.push(reference); } if (!element) { Ext.Error.raise("No 'element' reference found in '" + me.$className + "' template."); } if (renderElement === element.dom) { me.renderElement = element; } else { me.addElementReferenceOnDemand('renderElement', renderElement); } }, is: function(selector) { return Ext.ComponentQuery.is(this, selector); }, isXType: function(xtype, shallow) { return shallow ? (Ext.Array.indexOf(this.xtypes, xtype) !== -1) : !!this.xtypesMap[xtype]; }, resolveListenerScope: function(defaultType) { return this.mixins.inheritable.resolveListenerScope.call(this, defaultType); }, setSize: function(width, height) { if (width !== undefined) { this.setWidth(width); } if (height !== undefined) { this.setHeight(height); } }, privates: { addElementReferenceOnDemand: function(name, domNode) { if (this._elementListeners[name]) { this.addElementReference(name, domNode); } else { Ext.Object.defineProperty(this, name, { get: function() { delete this[name]; return this.addElementReference(name, domNode); }, configurable: true }); } }, addElementReference: function(name, domNode) { var me = this, referenceEl = me[name] = Ext.get(domNode), listeners = me._elementListeners[name], eventName, listener; referenceEl.skipGarbageCollection = true; referenceEl.component = me; if (listeners) { listeners = Ext.clone(listeners); listeners.scope = me; for (eventName in listeners) { listener = listeners[eventName]; if (typeof listener === 'object') { listener.scope = me; } } referenceEl.on(listeners); } return referenceEl; }, detachFromBody: function() { Ext.getDetachedBody().appendChild(this.element); this.isDetached = true; }, //@private doAddListener: function(name, fn, scope, options, order, caller, manager) { if (options && 'element' in options) { if (this.referenceList.indexOf(options.element) === -1) { Ext.Logger.error("Adding event listener with an invalid element reference of '" + options.element + "' for this component. Available values are: '" + this.referenceList.join("', '") + "'", this); } this[options.element].doAddListener(name, fn, scope || this, options, order); } this.callParent([ name, fn, scope, options, order, caller, manager ]); }, filterLengthValue: function(value) { if (value === 'auto' || (!value && value !== 0)) { return null; } return value; }, getFocusEl: function() { return this.element; }, initElementListeners: function(elementConfig) { var prototype = this, superPrototype = prototype.self.superclass, superElementListeners = superPrototype._elementListeners, reference = elementConfig.reference, children = elementConfig.children, elementListeners, listeners, superListeners, ln, i; if (prototype.hasOwnProperty('_elementListeners')) { elementListeners = prototype._elementListeners; } else { elementListeners = prototype._elementListeners = (superElementListeners ? Ext.Object.chain(superElementListeners) : {}); } if (reference) { listeners = elementConfig.listeners; if (listeners) { if (superElementListeners) { superListeners = superElementListeners[reference]; if (superListeners) { listeners = Ext.Object.chain(superListeners); Ext.apply(listeners, elementConfig.listeners); } } elementListeners[reference] = listeners; elementConfig.listeners = null; } } if (children) { for (i = 0 , ln = children.length; i < ln; i++) { prototype.initElementListeners(children[i]); } } }, initId: function(config) { var me = this, defaultConfig = me.config, id = (config && config.id) || (defaultConfig && defaultConfig.id); if (id) { me.setId(id); me.id = id; } else { me.getId(); } }, processElementConfig: function() { var prototype = this, superPrototype = prototype.self.superclass, elementConfig; if (prototype.hasOwnProperty('_elementConfig')) { elementConfig = prototype._elementConfig; } else { elementConfig = prototype._elementConfig = prototype.getElementConfig(); if (superPrototype.isWidget) { prototype.processElementConfig.call(superPrototype); } prototype.initElementListeners(elementConfig); } return elementConfig; }, reattachToBody: function() { this.isDetached = false; } } }, function(Widget) { (Widget.prototype.$elementEventOptions = Ext.Object.chain(Ext.Element.prototype.$eventOptions)).element = 1; }); Ext.define('Ext.overrides.Widget', { override: 'Ext.Widget', uses: [ 'Ext.Component' ], $configStrict: false, isComponent: true, liquidLayout: true, rendered: true, rendering: true, config: { renderTo: null }, cachedConfig: { baseCls: Ext.baseCSSPrefix + 'widget' }, constructor: function(config) { var me = this, renderTo; me.callParent([ config ]); me.getComponentLayout(); renderTo = me.getRenderTo(); if (renderTo) { me.render(renderTo); } }, addCls: function(cls) { this.el.addCls(cls); }, addClsWithUI: function(cls) { this.el.addCls(cls); }, afterComponentLayout: Ext.emptyFn, finishRender: function() { this.rendering = false; this.initBindable(); }, getComponentLayout: function() { var me = this, layout = me.componentLayout; if (!layout) { layout = me.componentLayout = new Ext.layout.component.Auto(); layout.setOwner(me); } return layout; }, getTdCls: function() { return Ext.baseCSSPrefix + this.getTdType() + '-' + (this.ui || 'default') + '-cell'; }, getTdType: function() { return this.xtype; }, getItemId: function() { return this.itemId || this.id; }, getSizeModel: function() { return Ext.Component.prototype.getSizeModel.apply(this, arguments); }, onAdded: function(container, pos, instanced) { var me = this, inheritedState = me.inheritedState; me.ownerCt = container; if (inheritedState && instanced) { me.invalidateInheritedState(); } if (me.reference) { me.fixReference(); } }, onRemoved: function(destroying) { var me = this, refHolder; if (me.reference) { refHolder = me.lookupReferenceHolder(); if (refHolder) { refHolder.clearReference(me); } } if (!destroying) { me.removeBindings(); } if (me.inheritedState && !destroying) { me.invalidateInheritedState(); } me.ownerCt = me.ownerLayout = null; }, parseBox: function(box) { return Ext.Element.parseBox(box); }, removeCls: function(cls) { this.el.removeCls(cls); }, removeClsWithUI: function(cls) { this.el.removeCls(cls); }, render: function(container, position) { var me = this, element = me.element, proto = Ext.Component.prototype, nextSibling; if (!me.ownerCt || me.floating) { if (Ext.scopeCss) { element.addCls(proto.rootCls); } element.addCls(proto.borderBoxCls); } if (position) { nextSibling = container.childNodes[position]; if (nextSibling) { Ext.fly(container).insertBefore(element, nextSibling); return; } } Ext.fly(container).appendChild(element); }, setPosition: function(x, y) { this.el.setLocalXY(x, y); }, up: function() { return Ext.Component.prototype.up.apply(this, arguments); }, isAncestor: function() { return Ext.Component.prototype.isAncestor.apply(this, arguments); }, onFocusEnter: function() { return Ext.Component.prototype.onFocusEnter.apply(this, arguments); }, onFocusLeave: function() { return Ext.Component.prototype.onFocusLeave.apply(this, arguments); }, focus: Ext.emptyFn, isFocusable: Ext.emptyFn }, function(Cls) { var prototype = Cls.prototype; if (Ext.isIE8) { prototype.addElementReferenceOnDemand = prototype.addElementReference; } }); Ext.define('Ext.util.XTemplateParser', { requires: [ 'Ext.String' ], constructor: function(config) { Ext.apply(this, config); }, doTpl: Ext.emptyFn, parse: function(str) { var me = this, len = str.length, aliases = { elseif: 'elif' }, topRe = me.topRe, actionsRe = me.actionsRe, index, stack, s, m, t, prev, frame, subMatch, begin, end, actions, prop, expectTplNext; me.level = 0; me.stack = stack = []; for (index = 0; index < len; index = end) { topRe.lastIndex = index; m = topRe.exec(str); if (!m) { me.doText(str.substring(index, len)); break; } begin = m.index; end = topRe.lastIndex; if (index < begin) { s = str.substring(index, begin); if (!(expectTplNext && Ext.String.trim(s) === '')) { me.doText(s); } } expectTplNext = false; if (m[1]) { end = str.indexOf('%}', begin + 2); me.doEval(str.substring(begin + 2, end)); end += 2; } else if (m[2]) { end = str.indexOf(']}', begin + 2); me.doExpr(str.substring(begin + 2, end)); end += 2; } else if (m[3]) { me.doTag(m[3]); } else if (m[4]) { actions = null; while ((subMatch = actionsRe.exec(m[4])) !== null) { s = subMatch[2] || subMatch[3]; if (s) { s = Ext.String.htmlDecode(s); t = subMatch[1]; t = aliases[t] || t; actions = actions || {}; prev = actions[t]; if (typeof prev == 'string') { actions[t] = [ prev, s ]; } else if (prev) { actions[t].push(s); } else { actions[t] = s; } } } if (!actions) { if (me.elseRe.test(m[4])) { me.doElse(); } else if (me.defaultRe.test(m[4])) { me.doDefault(); } else { me.doTpl(); stack.push({ type: 'tpl' }); } } else if (actions['if']) { me.doIf(actions['if'], actions); stack.push({ type: 'if' }); } else if (actions['switch']) { me.doSwitch(actions['switch'], actions); stack.push({ type: 'switch' }); expectTplNext = true; } else if (actions['case']) { me.doCase(actions['case'], actions); } else if (actions['elif']) { me.doElseIf(actions['elif'], actions); } else if (actions['for']) { ++me.level; if (prop = me.propRe.exec(m[4])) { actions.propName = prop[1] || prop[2]; } me.doFor(actions['for'], actions); stack.push({ type: 'for', actions: actions }); } else if (actions['foreach']) { ++me.level; if (prop = me.propRe.exec(m[4])) { actions.propName = prop[1] || prop[2]; } me.doForEach(actions['foreach'], actions); stack.push({ type: 'foreach', actions: actions }); } else if (actions.exec) { me.doExec(actions.exec, actions); stack.push({ type: 'exec', actions: actions }); } } else if (m[0].length === 5) { stack.push({ type: 'tpl' }); } else { frame = stack.pop(); me.doEnd(frame.type, frame.actions); if (frame.type == 'for' || frame.type == 'foreach') { --me.level; } } } }, topRe: /(?:(\{\%)|(\{\[)|\{([^{}]+)\})|(?:]*)\>)|(?:<\/tpl>)/g, actionsRe: /\s*(elif|elseif|if|for|foreach|exec|switch|case|eval|between)\s*\=\s*(?:(?:"([^"]*)")|(?:'([^']*)'))\s*/g, propRe: /prop=(?:(?:"([^"]*)")|(?:'([^']*)'))/, defaultRe: /^\s*default\s*$/, elseRe: /^\s*else\s*$/ }); Ext.define('Ext.util.XTemplateCompiler', { extend: 'Ext.util.XTemplateParser', useEval: Ext.isGecko, useIndex: Ext.isIE8m, useFormat: true, propNameRe: /^[\w\d\$]*$/, compile: function(tpl) { var me = this, code = me.generate(tpl); return me.useEval ? me.evalTpl(code) : (new Function('Ext', code))(Ext); }, generate: function(tpl) { var me = this, definitions = 'var fm=Ext.util.Format,ts=Object.prototype.toString;', code; me.maxLevel = 0; me.body = [ 'var c0=values, a0=' + me.createArrayTest(0) + ', p0=parent, n0=xcount, i0=xindex, k0, v;\n' ]; if (me.definitions) { if (typeof me.definitions === 'string') { me.definitions = [ me.definitions, definitions ]; } else { me.definitions.push(definitions); } } else { me.definitions = [ definitions ]; } me.switches = []; me.parse(tpl); me.definitions.push((me.useEval ? '$=' : 'return') + ' function (' + me.fnArgs + ') {', me.body.join(''), '}'); code = me.definitions.join('\n'); me.definitions.length = me.body.length = me.switches.length = 0; delete me.definitions; delete me.body; delete me.switches; return code; }, doText: function(text) { var me = this, out = me.body; text = text.replace(me.aposRe, "\\'").replace(me.newLineRe, '\\n'); if (me.useIndex) { out.push('out[out.length]=\'', text, '\'\n'); } else { out.push('out.push(\'', text, '\')\n'); } }, doExpr: function(expr) { var out = this.body; out.push('if ((v=' + expr + ') != null) out'); if (this.useIndex) { out.push('[out.length]=v+\'\'\n'); } else { out.push('.push(v+\'\')\n'); } }, doTag: function(tag) { var expr = this.parseTag(tag); if (expr) { this.doExpr(expr); } else { this.doText('{' + tag + '}'); } }, doElse: function() { this.body.push('} else {\n'); }, doEval: function(text) { this.body.push(text, '\n'); }, doIf: function(action, actions) { var me = this; if (action === '.') { me.body.push('if (values) {\n'); } else if (me.propNameRe.test(action)) { me.body.push('if (', me.parseTag(action), ') {\n'); } else { me.body.push('if (', me.addFn(action), me.callFn, ') {\n'); } if (actions.exec) { me.doExec(actions.exec); } }, doElseIf: function(action, actions) { var me = this; if (action === '.') { me.body.push('else if (values) {\n'); } else if (me.propNameRe.test(action)) { me.body.push('} else if (', me.parseTag(action), ') {\n'); } else { me.body.push('} else if (', me.addFn(action), me.callFn, ') {\n'); } if (actions.exec) { me.doExec(actions.exec); } }, doSwitch: function(action) { var me = this, key; if (action === '.' || action === '#') { key = action === '.' ? 'values' : 'xindex'; me.body.push('switch (', key, ') {\n'); } else if (me.propNameRe.test(action)) { me.body.push('switch (', me.parseTag(action), ') {\n'); } else { me.body.push('switch (', me.addFn(action), me.callFn, ') {\n'); } me.switches.push(0); }, doCase: function(action) { var me = this, cases = Ext.isArray(action) ? action : [ action ], n = me.switches.length - 1, match, i; if (me.switches[n]) { me.body.push('break;\n'); } else { me.switches[n]++; } for (i = 0 , n = cases.length; i < n; ++i) { match = me.intRe.exec(cases[i]); cases[i] = match ? match[1] : ("'" + cases[i].replace(me.aposRe, "\\'") + "'"); } me.body.push('case ', cases.join(': case '), ':\n'); }, doDefault: function() { var me = this, n = me.switches.length - 1; if (me.switches[n]) { me.body.push('break;\n'); } else { me.switches[n]++; } me.body.push('default:\n'); }, doEnd: function(type, actions) { var me = this, L = me.level - 1; if (type == 'for' || type == 'foreach') { if (actions.exec) { me.doExec(actions.exec); } me.body.push('}\n'); me.body.push('parent=p', L, ';values=r', L + 1, ';xcount=n' + L + ';xindex=i', L, '+1;xkey=k', L, ';\n'); } else if (type == 'if' || type == 'switch') { me.body.push('}\n'); } }, doFor: function(action, actions) { var me = this, s, L = me.level, up = L - 1, parentAssignment; if (action === '.') { s = 'values'; } else if (me.propNameRe.test(action)) { s = me.parseTag(action); } else { s = me.addFn(action) + me.callFn; } if (me.maxLevel < L) { me.maxLevel = L; me.body.push('var '); } if (action == '.') { parentAssignment = 'c' + L; } else { parentAssignment = 'a' + up + '?c' + up + '[i' + up + ']:c' + up; } me.body.push('i', L, '=0,n', L, '=0,c', L, '=', s, ',a', L, '=', me.createArrayTest(L), ',r', L, '=values,p', L, ',k', L, ';\n', 'p', L, '=parent=', parentAssignment, '\n', 'if (c', L, '){if(a', L, '){n', L, '=c', L, '.length;}else if (c', L, '.isMixedCollection){c', L, '=c', L, '.items;n', L, '=c', L, '.length;}else if(c', L, '.isStore){c', L, '=c', L, '.data.items;n', L, '=c', L, '.length;}else{c', L, '=[c', L, '];n', L, '=1;}}\n', 'for (xcount=n', L, ';i', L, '1){ out.push("', actions.between, '"); } \n'); } }, doForEach: function(action, actions) { var me = this, s, L = me.level, up = L - 1, parentAssignment; if (action === '.') { s = 'values'; } else if (me.propNameRe.test(action)) { s = me.parseTag(action); } else { s = me.addFn(action) + me.callFn; } if (me.maxLevel < L) { me.maxLevel = L; me.body.push('var '); } if (action == '.') { parentAssignment = 'c' + L; } else { parentAssignment = 'a' + up + '?c' + up + '[i' + up + ']:c' + up; } me.body.push('i', L, '=-1,n', L, '=0,c', L, '=', s, ',a', L, '=', me.createArrayTest(L), ',r', L, '=values,p', L, ',k', L, ';\n', 'p', L, '=parent=', parentAssignment, '\n', 'for(k', L, ' in c', L, '){\n', 'xindex=++i', L, '+1;\n', 'xkey=k', L, ';\n', 'values=c', L, '[k', L, '];'); if (actions.propName) { me.body.push('.', actions.propName); } if (actions.between) { me.body.push('if(xindex>1){ out.push("', actions.between, '"); } \n'); } }, createArrayTest: ('isArray' in Array) ? function(L) { return 'Array.isArray(c' + L + ')'; } : function(L) { return 'ts.call(c' + L + ')==="[object Array]"'; }, doExec: function(action, actions) { var me = this, name = 'f' + me.definitions.length, guards = me.guards[me.strict ? 0 : 1]; me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', guards.doTry, ' var $v = values; with($v) {', ' ' + action, ' }', guards.doCatch, '}'); me.body.push(name + me.callFn + '\n'); }, guards: [ { doTry: '', doCatch: '' }, { doTry: 'try { ', doCatch: ' } catch(e) {\n' + 'Ext.log.warn("XTemplate evaluation exception: " + e.message);\n' + '}' } ], addFn: function(body) { var me = this, name = 'f' + me.definitions.length, guards = me.guards[me.strict ? 0 : 1]; if (body === '.') { me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', ' return values', '}'); } else if (body === '..') { me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', ' return parent', '}'); } else { me.definitions.push('function ' + name + '(' + me.fnArgs + ') {', guards.doTry, ' var $v = values; with($v) {', ' return(' + body + ')', ' }', guards.doCatch, '}'); } return name; }, parseTag: function(tag) { var me = this, m = me.tagRe.exec(tag), name, format, args, math, v; if (!m) { return null; } name = m[1]; format = m[2]; args = m[3]; math = m[4]; if (name == '.') { if (!me.validTypes) { me.definitions.push('var validTypes={string:1,number:1,boolean:1};'); me.validTypes = true; } v = 'validTypes[typeof values] || ts.call(values) === "[object Date]" ? values : ""'; } else if (name == '#') { v = 'xindex'; } else if (name == '$') { v = 'xkey'; } else if (name.substr(0, 7) == "parent.") { v = name; } else if (isNaN(name) && name.indexOf('-') == -1 && name.indexOf('.') != -1) { v = "values." + name; } else { v = "values['" + name + "']"; } if (math) { v = '(' + v + math + ')'; } if (format && me.useFormat) { args = args ? ',' + args : ""; if (format.substr(0, 5) != "this.") { format = "fm." + format + '('; } else { format += '('; } } else { return v; } return format + v + args + ')'; }, evalTpl: function($) { eval($); return $; }, newLineRe: /\r\n|\r|\n/g, aposRe: /[']/g, intRe: /^\s*(\d+)\s*$/, tagRe: /^([\w-\.\#\$]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\/]\s?[\d\.\+\-\*\/\(\)]+)?$/ }, function() { var proto = this.prototype; proto.fnArgs = 'out,values,parent,xindex,xcount,xkey'; proto.callFn = '.call(this,' + proto.fnArgs + ')'; }); Ext.define('Ext.XTemplate', { extend: 'Ext.Template', requires: [ 'Ext.util.XTemplateCompiler' ], emptyObj: {}, fn: null, strict: false, apply: function(values, parent) { return this.applyOut(values, [], parent).join(''); }, applyOut: function(values, out, parent) { var me = this, compiler; if (!me.fn) { compiler = new Ext.util.XTemplateCompiler({ useFormat: me.disableFormats !== true, definitions: me.definitions, strict: me.strict }); me.fn = compiler.compile(me.html); } if (me.strict) { me.fn(out, values, parent || me.emptyObj, 1, 1); } else { try { me.fn(out, values, parent || me.emptyObj, 1, 1); } catch (e) { Ext.log.warn('XTemplate evaluation exception: ' + e.message); } } return out; }, compile: function() { return this; }, statics: { getTpl: function(instance, name) { var tpl = instance[name], owner; if (tpl && !tpl.isTemplate) { tpl = Ext.ClassManager.dynInstantiate('Ext.XTemplate', tpl); if (instance.hasOwnProperty(name)) { owner = instance; } else { for (owner = instance.self.prototype; owner && !owner.hasOwnProperty(name); owner = owner.superclass) {} } owner[name] = tpl; tpl.owner = owner; } return tpl || null; } } }); Ext.define('Ext.app.EventDomain', { requires: [ 'Ext.util.Event' ], statics: { instances: {} }, isEventDomain: true, isInstance: false, constructor: function() { var me = this; if (!me.isInstance) { Ext.app.EventDomain.instances[me.type] = me; } me.bus = {}; me.monitoredClasses = []; }, dispatch: function(target, ev, args) { ev = Ext.canonicalEventName(ev); var me = this, bus = me.bus, selectors = bus[ev], selector, controllers, id, info, events, len, i, event; if (!selectors) { return true; } for (selector in selectors) { if (selectors.hasOwnProperty(selector) && me.match(target, selector, me.controller)) { controllers = selectors[selector]; for (id in controllers) { if (controllers.hasOwnProperty(id)) { info = controllers[id]; if (info.controller.isActive()) { events = info.list; len = events.length; for (i = 0; i < len; i++) { event = events[i]; if (event.fire.apply(event, args) === false) { return false; } } } } } } } return true; }, listen: function(selectors, controller) { var me = this, bus = me.bus, idProperty = me.idProperty, monitoredClasses = me.monitoredClasses, monitoredClassesCount = monitoredClasses.length, controllerId = controller.getId(), isComponentDomain = (me.type === 'component'), refMap = isComponentDomain ? controller.getRefMap() : null, i, tree, info, selector, options, listener, scope, event, listeners, ev, classHasListeners; for (selector in selectors) { listeners = selectors[selector]; if (isComponentDomain) { selector = refMap[selector] || selector; } if (listeners) { if (idProperty) { if (!/^[*#]/.test(selector)) { Ext.Error.raise('Selectors containing id should begin with #'); } selector = selector === '*' ? selector : selector.substring(1); } for (ev in listeners) { options = null; listener = listeners[ev]; scope = controller; ev = Ext.canonicalEventName(ev); event = new Ext.util.Event(controller, ev); if (Ext.isObject(listener)) { options = listener; listener = options.fn; scope = options.scope || controller; delete options.fn; delete options.scope; } if ((!options || !options.scope) && typeof listener === 'string') { if (!scope[listener]) { Ext.Error.raise('Cannot resolve "' + listener + '" on controller.'); } scope = null; } else if (typeof listener === 'string') { listener = scope[listener]; } event.addListener(listener, scope, options); for (i = 0; i < monitoredClassesCount; ++i) { classHasListeners = monitoredClasses[i].hasListeners; if (classHasListeners) { classHasListeners._incr_(ev); } } tree = bus[ev] || (bus[ev] = {}); tree = tree[selector] || (tree[selector] = {}); info = tree[controllerId] || (tree[controllerId] = { controller: controller, list: [] }); info.list.push(event); } } } }, match: function(target, selector) { var idProperty = this.idProperty; if (idProperty) { return selector === '*' || target[idProperty] === selector; } return false; }, monitor: function(observable) { var domain = this, prototype = observable.isInstance ? observable : observable.prototype, doFireEvent = prototype.doFireEvent; domain.monitoredClasses.push(observable); prototype.doFireEvent = function(ev, args) { var ret = doFireEvent.apply(this, arguments); if (ret !== false && !this.isSuspended(ev)) { ret = domain.dispatch(this, ev, args); } return ret; }; }, unlisten: function(controllerId) { var bus = this.bus, id = controllerId, monitoredClasses = this.monitoredClasses, monitoredClassesCount = monitoredClasses.length, controllers, ev, events, len, item, selector, selectors, i, j, info, classHasListeners; if (controllerId.isController) { id = controllerId.getId(); } for (ev in bus) { ev = Ext.canonicalEventName(ev); if (bus.hasOwnProperty(ev) && (selectors = bus[ev])) { for (selector in selectors) { controllers = selectors[selector]; info = controllers[id]; if (info) { events = info.list; if (events) { for (i = 0 , len = events.length; i < len; ++i) { item = events[i]; item.clearListeners(); for (j = 0; j < monitoredClassesCount; ++j) { classHasListeners = monitoredClasses[j].hasListeners; if (classHasListeners) { classHasListeners._decr_(item.name); } } } delete controllers[id]; } } } } } }, destroy: function() { this.monitoredClasses = this.bus = null; } }); Ext.define('Ext.app.domain.Component', { extend: 'Ext.app.EventDomain', singleton: true, requires: [ 'Ext.Widget' ], type: 'component', constructor: function() { this.callParent(); this.monitor(Ext.Widget); }, dispatch: function(target, ev, args) { var controller = target.lookupController(false), domain, view; while (controller) { domain = controller.compDomain; if (domain) { if (domain.dispatch(target, ev, args) === false) { return false; } } view = controller.getView(); controller = view ? view.lookupController(true) : null; } return this.callParent(arguments); }, match: function(target, selector) { return target.is(selector); } }); Ext.define('Ext.util.ProtoElement', function() { var splitWords = Ext.String.splitWords, toMap = Ext.Array.toMap; return { isProtoEl: true, clsProp: 'cls', styleProp: 'style', removedProp: 'removed', styleIsText: false, constructor: function(config) { var me = this, cls, style; if (config) { Ext.apply(me, config); cls = me.cls; style = me.style; delete me.cls; } me.classList = cls ? splitWords(cls) : []; me.classMap = cls ? toMap(me.classList) : {}; if (style) { if (typeof style === 'string') { me.style = Ext.Element.parseStyles(style); } else if (Ext.isFunction(style)) { me.styleFn = style; delete me.style; } else { me.style = Ext.apply({}, style); } } }, flush: function() { this.flushClassList = []; this.removedClasses = {}; delete this.style; delete this.unselectableAttr; }, addCls: function(cls) { if (!cls) { return this; } var me = this, add = (typeof cls === 'string') ? splitWords(cls) : cls, length = add.length, list = me.classList, map = me.classMap, flushList = me.flushClassList, i = 0, c; for (; i < length; ++i) { c = add[i]; if (!map[c]) { map[c] = true; list.push(c); if (flushList) { flushList.push(c); delete me.removedClasses[c]; } } } return me; }, hasCls: function(cls) { return cls in this.classMap; }, removeCls: function(cls) { var me = this, list = me.classList, newList = (me.classList = []), remove = toMap(splitWords(cls)), length = list.length, map = me.classMap, removedClasses = me.removedClasses, i, c; for (i = 0; i < length; ++i) { c = list[i]; if (remove[c]) { if (removedClasses) { if (map[c]) { removedClasses[c] = true; Ext.Array.remove(me.flushClassList, c); } } delete map[c]; } else { newList.push(c); } } return me; }, setStyle: function(prop, value) { var me = this, style = me.style || (me.style = {}); if (typeof prop === 'string') { if (arguments.length === 1) { me.setStyle(Ext.Element.parseStyles(prop)); } else { style[prop] = value; } } else { Ext.apply(style, prop); } return me; }, unselectable: function() { this.addCls(Ext.dom.Element.unselectableCls); if (Ext.isOpera) { this.unselectableAttr = true; } }, writeTo: function(to) { var me = this, classList = me.flushClassList || me.classList, removedClasses = me.removedClasses, style; if (me.styleFn) { style = Ext.apply({}, me.styleFn()); Ext.apply(style, me.style); } else { style = me.style; } to[me.clsProp] = classList.join(' '); if (style) { to[me.styleProp] = me.styleIsText ? Ext.DomHelper.generateStyles(style, null, true) : style; } if (removedClasses) { removedClasses = Ext.Object.getKeys(removedClasses); if (removedClasses.length) { to[me.removedProp] = removedClasses.join(' '); } } if (me.unselectableAttr) { to.unselectable = 'on'; } return to; } }; }); Ext.define('Ext.dom.CompositeElement', { alternateClassName: 'Ext.CompositeElement', extend: 'Ext.dom.CompositeElementLite', isLite: false, getElement: function(el) { return el; }, transformElement: function(el) { return Ext.get(el); } }); Ext.Factory = function(type) { var me = this; me.aliasPrefix = type + '.'; me.cache = {}; me.name = type.replace(me.fixNameRe, me.fixNameFn); me.type = type; }; Ext.Factory.prototype = { defaultProperty: 'type', instanceProp: 'isInstance', create: function(config, defaultType) { var me = this, Manager = Ext.ClassManager, cache = me.cache, alias, className, klass, suffix; if (config) { if (config[me.instanceProp]) { return config; } if (typeof config === 'string') { suffix = config; config = {}; config[me.defaultProperty] = suffix; } className = config.xclass; suffix = config.type; } if (className) { if (!(klass = Manager.get(className))) { return Manager.instantiate(className, config); } } else { if (!(suffix = suffix || defaultType || me.defaultType)) { klass = me.defaultClass; } if (!suffix && !klass) { Ext.Error.raise('No type specified for ' + me.type + '.create'); } if (!klass && !(klass = cache[suffix])) { alias = me.aliasPrefix + suffix; className = Manager.getNameByAlias(alias); if (!(klass = className && Manager.get(className))) { return Manager.instantiateByAlias(alias, config); } cache[suffix] = klass; } } return klass.isInstance ? klass : new klass(config); }, fixNameRe: /\.[a-z]/ig, fixNameFn: function(match) { return match.substring(1).toUpperCase(); }, clearCache: function() { this.cache = {}; } }; Ext.Factory.define = function(type, config) { var Factory = Ext.Factory, defaultClass, factory, fn; if (type.constructor === Object) { Ext.Object.each(type, Factory.define, Factory); } else { factory = new Ext.Factory(type); if (config) { if (config.constructor === Object) { Ext.apply(factory, config); if (typeof (defaultClass = factory.xclass) === 'string') { factory.defaultClass = Ext.ClassManager.get(defaultClass); } } else { factory.defaultType = config; } } Factory[factory.name] = fn = factory.create.bind(factory); fn.instance = factory; } return fn; }; Ext.define('Ext.mixin.Factoryable', { mixinId: 'factoryable', onClassMixedIn: function(targetClass) { var proto = targetClass.prototype, factoryConfig = proto.factoryConfig, alias = proto.alias, config = {}, dot, createFn; alias = alias && alias.length && alias[0]; if (alias && (dot = alias.lastIndexOf('.')) > 0) { config.type = alias.substring(0, dot); config.defaultType = alias.substring(dot + 1); } if (factoryConfig) { delete proto.factoryConfig; Ext.apply(config, factoryConfig); } createFn = Ext.Factory.define(config.type, config); if (targetClass.create === Ext.Base.create) { targetClass.create = createFn; } } }); Ext.define('Ext.scroll.Scroller', { extend: 'Ext.Evented', alias: 'scroller.scroller', mixins: [ 'Ext.mixin.Factoryable' ], uses: [ 'Ext.scroll.TouchScroller', 'Ext.scroll.DomScroller' ], factoryConfig: { defaultType: 'dom' }, isScroller: true, config: { direction: undefined, directionLock: false, disabled: null, element: undefined, indicators: null, maxPosition: null, maxUserPosition: null, minPosition: { x: 0, y: 0 }, minUserPosition: { x: 0, y: 0 }, momentumEasing: null, size: null, x: true, y: true }, statics: { create: function(config) { return Ext.Factory.scroller(config, Ext.supports.Touch ? 'touch' : 'dom'); } }, constructor: function(config) { var me = this; me.callParent([ config ]); me.onDomScrollEnd = Ext.Function.createBuffered(me.onDomScrollEnd, 100, me); }, addPartner: function(partner, axis) { var me = this, partners = me._partners || (me._partners = {}), otherPartners = partner._partners || (partner._partners = {}); partners[partner.getId()] = { scroller: partner, axis: axis }; otherPartners[me.getId()] = { scroller: me, axis: axis }; }, applyElement: function(element) { var el; if (element) { if (element.isElement) { el = element; } else { el = Ext.get(element); if (!el && (typeof element === 'string')) { Ext.Error.raise("Cannot create Ext.scroll.Scroller instance. " + "Element with id '" + element + "' not found."); } } } return el; }, updateDirectionLock: Ext.emptyFn, updateDisabled: Ext.emptyFn, updateIndicators: Ext.emptyFn, updateMaxPosition: Ext.emptyFn, updateMaxUserPosition: Ext.emptyFn, updateMinPosition: Ext.emptyFn, updateMinUserPosition: Ext.emptyFn, updateMomenumEasing: Ext.emptyFn, updateSize: Ext.emptyFn, updateX: Ext.emptyFn, updateY: Ext.emptyFn, updateElement: function(element) { element.on('scroll', 'onDomScroll', this); }, refresh: function() { this.fireEvent('refresh', this); return this; }, removePartner: function(partner) { var partners = this._partners, otherPartners = partner._partners; if (partners) { delete partners[partner.getId()]; } if (otherPartners) { delete (otherPartners[this.getId()]); } }, scrollBy: function(deltaX, deltaY, animate) { var position = this.getPosition(); if (deltaX) { if (deltaX.length) { animate = deltaY; deltaY = deltaX[1]; deltaX = deltaX[0]; } else if (typeof deltaX !== 'number') { animate = deltaY; deltaY = deltaX.y; deltaX = deltaX.x; } } deltaX = (typeof deltaX === 'number') ? deltaX + position.x : null; deltaY = (typeof deltaY === 'number') ? deltaY + position.y : null; return this.doScrollTo(deltaX, deltaY, animate); }, scrollIntoView: function(el, hscroll, animate, highlight) { var me = this, position = me.getPosition(), newPosition, newX, newY, myEl = me.getElement(); if (el) { newPosition = Ext.fly(el).getScrollIntoViewXY(myEl, position.x, position.y); newX = (hscroll === false) ? position.x : newPosition.x; newY = newPosition.y; if (highlight) { me.on({ scrollend: 'doHighlight', scope: me, single: true, args: [ el, highlight ] }); } me.doScrollTo(newX, newY, animate); } }, scrollTo: function(x, y, animate) { var maxPosition; if (x) { if (x.length) { animate = y; y = x[1]; x = x[0]; } else if (typeof x !== 'number') { animate = y; y = x.y; x = x.x; } } if (x < 0 || y < 0) { maxPosition = this.getMaxPosition(); if (x < 0) { x += maxPosition.x; } if (y < 0) { y += maxPosition.y; } } this.doScrollTo(x, y, animate); }, updateDirection: function(direction) { var me = this, x, y; if (!direction) { x = me.getX(); y = me.getY(); if (x && y) { direction = (y === 'scroll' && x === 'scroll') ? 'both' : 'auto'; } else if (y) { direction = 'vertical'; } else if (x) { direction = 'horizontal'; } me._direction = direction; } else { if (direction === 'auto') { x = true; y = true; } else if (direction === 'vertical') { x = false; y = true; } else if (direction === 'horizontal') { x = true; y = false; } else if (direction === 'both') { x = 'scroll'; y = 'scroll'; } me.setX(x); me.setY(y); } }, deprecated: { '5': { methods: { getScroller: function() { return this; } } }, '5.1.0': { methods: { scrollToTop: function(animate) { return this.scrollTo(0, 0, animate); }, scrollToEnd: function(animate) { return this.scrollTo(Infinity, Infinity, animate); } } } }, privates: { convertX: function(x) { return x; }, doHighlight: function(el, highlight) { if (highlight !== true) { Ext.fly(el).highlight(highlight); } else { Ext.fly(el).highlight(); } }, fireScrollStart: function(x, y) { var me = this, component = me.component; me.invokePartners('onPartnerScrollStart', x, y); if (me.hasListeners.scrollstart) { me.fireEvent('scrollstart', me, x, y); } if (component && component.onScrollStart) { component.onScrollStart(x, y); } Ext.GlobalEvents.fireEvent('scrollstart', me, x, y); }, fireScroll: function(x, y) { var me = this, component = me.component; me.invokePartners('onPartnerScroll', x, y); if (me.hasListeners.scroll) { me.fireEvent('scroll', me, x, y); } if (component && component.onScrollMove) { component.onScrollMove(x, y); } Ext.GlobalEvents.fireEvent('scroll', me, x, y); }, fireScrollEnd: function(x, y) { var me = this, component = me.component; me.invokePartners('onPartnerScrollEnd', x, y); if (me.hasListeners.scrollend) { me.fireEvent('scrollend', me, x, y); } if (component && component.onScrollEnd) { component.onScrollEnd(x, y); } Ext.GlobalEvents.fireEvent('scrollend', me, x, y); }, initXStyle: function() { var element = this.getElement(), x = this.getX(); if (!x) { x = 'hidden'; } else if (x === true) { x = 'auto'; } if (element) { element.setStyle('overflow-x', x); } }, initYStyle: function() { var element = this.getElement(), y = this.getY(); if (!y) { y = 'hidden'; } else if (y === true) { y = 'auto'; } if (element) { element.setStyle('overflow-y', y); } }, invokePartners: function(method, x, y) { var partners = this._partners, partner, id; if (!this.suspendSync) { for (id in partners) { partner = partners[id].scroller; partner[method](this, x, y); } } }, suspendPartnerSync: function() { this.suspendSync = (this.suspendSync || 0) + 1; }, resumePartnerSync: function() { if (this.suspendSync) { this.suspendSync--; } }, onDomScroll: function() { var me = this, position = me.getPosition(), x = position.x, y = position.y; if (!me.isScrolling) { me.isScrolling = true; me.fireScrollStart(x, y); } me.fireScroll(x, y); me.onDomScrollEnd(); }, onDomScrollEnd: function() { var me = this, position = me.getPosition(), x = position.x, y = position.y; me.isScrolling = false; me.trackingScrollLeft = x; me.trackingScrollTop = y; me.fireScrollEnd(x, y); }, onPartnerScroll: function(partner, x, y) { var axis = partner._partners[this.getId()].axis; if (axis) { if (axis === 'x') { y = null; } else if (axis === 'y') { x = null; } } this.doScrollTo(x, y); }, restoreState: function() { var me = this, el = me.getElement(), dom; if (el) { dom = el.dom; if (me.trackingScrollTop !== undefined) { dom.scrollTop = me.trackingScrollTop; dom.scrollLeft = me.trackingScrollLeft; } } }, onPartnerScrollStart: function() { this.suspendPartnerSync(); }, onPartnerScrollEnd: function() { this.resumePartnerSync(); } } }); Ext.define('Ext.fx.easing.Abstract', { config: { startTime: 0, startValue: 0 }, isEasing: true, isEnded: false, constructor: function(config) { this.initConfig(config); return this; }, applyStartTime: function(startTime) { if (!startTime) { startTime = Ext.Date.now(); } return startTime; }, updateStartTime: function(startTime) { this.reset(); }, reset: function() { this.isEnded = false; }, getValue: Ext.emptyFn }); Ext.define('Ext.fx.easing.Momentum', { extend: 'Ext.fx.easing.Abstract', config: { acceleration: 30, friction: 0, startVelocity: 0 }, alpha: 0, updateFriction: function(friction) { var theta = Math.log(1 - (friction / 10)); this.theta = theta; this.alpha = theta / this.getAcceleration(); }, updateStartVelocity: function(velocity) { this.velocity = velocity * this.getAcceleration(); }, updateAcceleration: function(acceleration) { this.velocity = this.getStartVelocity() * acceleration; this.alpha = this.theta / acceleration; }, getValue: function() { return this.getStartValue() - this.velocity * (1 - this.getFrictionFactor()) / this.theta; }, getFrictionFactor: function() { var deltaTime = Ext.Date.now() - this.getStartTime(); return Math.exp(deltaTime * this.alpha); }, getVelocity: function() { return this.getFrictionFactor() * this.velocity; } }); Ext.define('Ext.fx.easing.Bounce', { extend: 'Ext.fx.easing.Abstract', config: { springTension: 0.3, acceleration: 30, startVelocity: 0 }, getValue: function() { var deltaTime = Ext.Date.now() - this.getStartTime(), theta = (deltaTime / this.getAcceleration()), powTime = theta * Math.pow(Math.E, -this.getSpringTension() * theta); return this.getStartValue() + (this.getStartVelocity() * powTime); } }); Ext.define('Ext.fx.easing.BoundMomentum', { extend: 'Ext.fx.easing.Abstract', requires: [ 'Ext.fx.easing.Momentum', 'Ext.fx.easing.Bounce' ], config: { momentum: null, bounce: null, minMomentumValue: 0, maxMomentumValue: 0, minVelocity: 0.01, startVelocity: 0 }, applyMomentum: function(config, currentEasing) { return Ext.factory(config, Ext.fx.easing.Momentum, currentEasing); }, applyBounce: function(config, currentEasing) { return Ext.factory(config, Ext.fx.easing.Bounce, currentEasing); }, updateStartTime: function(startTime) { this.getMomentum().setStartTime(startTime); this.callParent(arguments); }, updateStartVelocity: function(startVelocity) { this.getMomentum().setStartVelocity(startVelocity); }, updateStartValue: function(startValue) { this.getMomentum().setStartValue(startValue); }, reset: function() { this.lastValue = null; this.isBouncingBack = false; this.isOutOfBound = false; return this.callParent(arguments); }, getValue: function() { var momentum = this.getMomentum(), bounce = this.getBounce(), startVelocity = momentum.getStartVelocity(), direction = startVelocity > 0 ? 1 : -1, minValue = this.getMinMomentumValue(), maxValue = this.getMaxMomentumValue(), boundedValue = (direction == 1) ? maxValue : minValue, lastValue = this.lastValue, value, velocity; if (startVelocity === 0) { return this.getStartValue(); } if (!this.isOutOfBound) { value = momentum.getValue(); velocity = momentum.getVelocity(); if (Math.abs(velocity) < this.getMinVelocity()) { this.isEnded = true; } if (value >= minValue && value <= maxValue) { return value; } this.isOutOfBound = true; bounce.setStartTime(Ext.Date.now()).setStartVelocity(velocity).setStartValue(boundedValue); } value = bounce.getValue(); if (!this.isEnded) { if (!this.isBouncingBack) { if (lastValue !== null) { if ((direction == 1 && value < lastValue) || (direction == -1 && value > lastValue)) { this.isBouncingBack = true; } } } else { if (Math.round(value) == boundedValue) { this.isEnded = true; } } } this.lastValue = value; return value; } }); Ext.define('Ext.fx.easing.Linear', { extend: 'Ext.fx.easing.Abstract', alias: 'easing.linear', config: { duration: 0, endValue: 0 }, updateStartValue: function(startValue) { this.distance = this.getEndValue() - startValue; }, updateEndValue: function(endValue) { this.distance = endValue - this.getStartValue(); }, getValue: function() { var deltaTime = Ext.Date.now() - this.getStartTime(), duration = this.getDuration(); if (deltaTime > duration) { this.isEnded = true; return this.getEndValue(); } else { return this.getStartValue() + ((deltaTime / duration) * this.distance); } } }); Ext.define('Ext.fx.easing.EaseOut', { extend: 'Ext.fx.easing.Linear', alias: 'easing.ease-out', config: { exponent: 4, duration: 1500 }, getValue: function() { var deltaTime = Ext.Date.now() - this.getStartTime(), duration = this.getDuration(), startValue = this.getStartValue(), endValue = this.getEndValue(), distance = this.distance, theta = deltaTime / duration, thetaC = 1 - theta, thetaEnd = 1 - Math.pow(thetaC, this.getExponent()), currentValue = startValue + (thetaEnd * distance); if (deltaTime >= duration) { this.isEnded = true; return endValue; } return currentValue; } }); Ext.define('Ext.util.translatable.Abstract', { extend: 'Ext.Evented', requires: [ 'Ext.fx.easing.Linear' ], config: { useWrapper: null, easing: null, easingX: null, easingY: null }, x: 0, y: 0, activeEasingX: null, activeEasingY: null, isAnimating: false, isTranslatable: true, constructor: function(config) { this.mixins.observable.constructor.call(this, config); this.position = { x: 0, y: 0 }; }, factoryEasing: function(easing) { return Ext.factory(easing, Ext.fx.easing.Linear, null, 'easing'); }, applyEasing: function(easing) { if (!this.getEasingX()) { this.setEasingX(this.factoryEasing(easing)); } if (!this.getEasingY()) { this.setEasingY(this.factoryEasing(easing)); } }, applyEasingX: function(easing) { return this.factoryEasing(easing); }, applyEasingY: function(easing) { return this.factoryEasing(easing); }, doTranslate: Ext.emptyFn, translate: function(x, y, animation) { if (animation) { return this.translateAnimated(x, y, animation); } if (this.isAnimating) { this.stopAnimation(); } if (!isNaN(x) && typeof x == 'number') { this.x = x; } if (!isNaN(y) && typeof y == 'number') { this.y = y; } this.doTranslate(x, y); }, translateAxis: function(axis, value, animation) { var x, y; if (axis == 'x') { x = value; } else { y = value; } return this.translate(x, y, animation); }, getPosition: function() { var me = this, position = me.position; position.x = -me.x; position.y = -me.y; return position; }, animate: function(easingX, easingY) { this.activeEasingX = easingX; this.activeEasingY = easingY; this.isAnimating = true; this.lastX = null; this.lastY = null; Ext.AnimationQueue.start(this.doAnimationFrame, this); this.fireEvent('animationstart', this, this.x, this.y); return this; }, translateAnimated: function(x, y, animation) { var me = this; if (!Ext.isObject(animation)) { animation = {}; } if (me.isAnimating) { me.stopAnimation(); } me.callback = animation.callback; me.callbackScope = animation.scope; var now = Ext.Date.now(), easing = animation.easing, easingX = (typeof x == 'number') ? (animation.easingX || easing || me.getEasingX() || true) : null, easingY = (typeof y == 'number') ? (animation.easingY || easing || me.getEasingY() || true) : null; if (easingX) { easingX = me.factoryEasing(easingX); easingX.setStartTime(now); easingX.setStartValue(me.x); easingX.setEndValue(x); if ('duration' in animation) { easingX.setDuration(animation.duration); } } if (easingY) { easingY = me.factoryEasing(easingY); easingY.setStartTime(now); easingY.setStartValue(me.y); easingY.setEndValue(y); if ('duration' in animation) { easingY.setDuration(animation.duration); } } return me.animate(easingX, easingY); }, doAnimationFrame: function() { var me = this, easingX = me.activeEasingX, easingY = me.activeEasingY, now = Date.now(), x, y; if (!me.isAnimating) { return; } me.lastRun = now; if (easingX === null && easingY === null) { me.stopAnimation(); return; } if (easingX !== null) { me.x = x = Math.round(easingX.getValue()); if (easingX.isEnded) { me.activeEasingX = null; me.fireEvent('axisanimationend', me, 'x', x); } } else { x = me.x; } if (easingY !== null) { me.y = y = Math.round(easingY.getValue()); if (easingY.isEnded) { me.activeEasingY = null; me.fireEvent('axisanimationend', me, 'y', y); } } else { y = me.y; } if (me.lastX !== x || me.lastY !== y) { me.doTranslate(x, y); me.lastX = x; me.lastY = y; } me.fireEvent('animationframe', me, x, y); }, stopAnimation: function() { var me = this; if (!me.isAnimating) { return; } me.activeEasingX = null; me.activeEasingY = null; me.isAnimating = false; Ext.AnimationQueue.stop(me.doAnimationFrame, me); me.fireEvent('animationend', me, me.x, me.y); if (me.callback) { me.callback.call(me.callbackScope); me.callback = null; } }, refresh: function() { this.translate(this.x, this.y); }, destroy: function() { if (this.isAnimating) { this.stopAnimation(); } this.callParent(arguments); } }); Ext.define('Ext.util.translatable.Dom', { extend: 'Ext.util.translatable.Abstract', config: { element: null }, applyElement: function(element) { if (!element) { return; } return Ext.get(element); }, updateElement: function() { this.refresh(); } }); Ext.define('Ext.util.translatable.CssTransform', { extend: 'Ext.util.translatable.Dom', doTranslate: function(x, y) { var element = this.getElement(); if (!this.isDestroyed && !element.isDestroyed) { element.translate(x, y); } }, destroy: function() { var element = this.getElement(); if (element && !element.isDestroyed) { element.dom.style.webkitTransform = null; } this.callParent(); } }); Ext.define('Ext.util.translatable.ScrollPosition', { extend: 'Ext.util.translatable.Dom', type: 'scrollposition', config: { useWrapper: true }, getWrapper: function() { var wrapper = this.wrapper, element = this.getElement(), container; if (!wrapper) { container = element.getParent(); if (!container) { return null; } if (container.hasCls(Ext.baseCSSPrefix + 'translatable-hboxfix')) { container = container.getParent(); } if (this.getUseWrapper()) { wrapper = element.wrap(); } else { wrapper = container; } element.addCls(Ext.baseCSSPrefix + 'translatable'); wrapper.addCls(Ext.baseCSSPrefix + 'translatable-container'); this.wrapper = wrapper; wrapper.on('painted', function() { if (!this.isAnimating) { this.refresh(); } }, this); this.refresh(); } return wrapper; }, doTranslate: function(x, y) { var wrapper = this.getWrapper(), dom; if (wrapper) { dom = wrapper.dom; if (typeof x == 'number') { dom.scrollLeft = 500000 - x; } if (typeof y == 'number') { dom.scrollTop = 500000 - y; } } }, destroy: function() { var element = this.getElement(), wrapper = this.wrapper; if (wrapper) { if (!element.isDestroyed) { if (this.getUseWrapper()) { wrapper.doReplaceWith(element); } element.removeCls(Ext.baseCSSPrefix + 'translatable'); } if (!wrapper.isDestroyed) { wrapper.removeCls(Ext.baseCSSPrefix + 'translatable-container'); wrapper.un('painted', 'refresh', this); } delete this.wrapper; delete this._element; } this.callParent(); } }); Ext.define('Ext.util.translatable.ScrollParent', { extend: 'Ext.util.translatable.Dom', isScrollParent: true, applyElement: function(element) { var el = Ext.get(element); if (el) { this.parent = el.parent(); } return el; }, doTranslate: function(x, y) { var parent = this.parent; parent.setScrollLeft(Math.round(-x)); parent.setScrollTop(Math.round(-y)); }, getPosition: function() { var me = this, position = me.position, parent = me.parent; position.x = parent.getScrollLeft(); position.y = parent.getScrollTop(); return position; } }); Ext.define('Ext.util.translatable.CssPosition', { extend: 'Ext.util.translatable.Dom', doTranslate: function(x, y) { var domStyle = this.getElement().dom.style; if (typeof x == 'number') { domStyle.left = x + 'px'; } if (typeof y == 'number') { domStyle.top = y + 'px'; } }, destroy: function() { var domStyle = this.getElement().dom.style; domStyle.left = null; domStyle.top = null; this.callParent(arguments); } }); Ext.define('Ext.util.Translatable', { requires: [ 'Ext.util.translatable.CssTransform', 'Ext.util.translatable.ScrollPosition', 'Ext.util.translatable.ScrollParent', 'Ext.util.translatable.CssPosition' ], constructor: function(config) { var namespace = Ext.util.translatable; switch (Ext.browser.getPreferredTranslationMethod(config)) { case 'scrollposition': return new namespace.ScrollPosition(config); case 'scrollparent': return new namespace.ScrollParent(config); case 'csstransform': return new namespace.CssTransform(config); case 'cssposition': return new namespace.CssPosition(config); } } }); Ext.define('Ext.scroll.Indicator', { extend: 'Ext.Widget', xtype: 'scrollindicator', config: { axis: null, hideAnimation: true, hideDelay: 0, scroller: null, minLength: 24 }, defaultHideAnimation: { to: { opacity: 0 }, duration: 300 }, names: { x: { side: 'l', getSize: 'getHeight', setLength: 'setWidth', translate: 'translateX' }, y: { side: 't', getSize: 'getWidth', setLength: 'setHeight', translate: 'translateY' } }, oppositeAxis: { x: 'y', y: 'x' }, cls: Ext.baseCSSPrefix + 'scroll-indicator', applyHideAnimation: function(hideAnimation) { if (hideAnimation) { hideAnimation = Ext.mergeIf({ onEnd: this.onHideAnimationEnd, scope: this }, this.defaultHideAnimation, hideAnimation); } return hideAnimation; }, constructor: function(config) { var me = this, axis; me.callParent([ config ]); axis = me.getAxis(); me.names = me.names[axis]; me.element.addCls(me.cls + ' ' + me.cls + '-' + axis); }, hide: function() { var me = this, delay = me.getHideDelay(); if (delay) { me._hideTimer = Ext.defer(me.doHide, delay, me); } else { me.doHide(); } }, setValue: function(value) { var me = this, el = me.element, names = me.names, axis = me.getAxis(), scroller = me.getScroller(), maxScrollPosition = scroller.getMaxUserPosition()[axis], elementSize = scroller.getElementSize()[axis], baseLength = me.length, minLength = me.getMinLength(), length = baseLength, maxPosition = elementSize - baseLength - me.sizeAdjust, round = Math.round, max = Math.max, position; if (value < 0) { length = round(max(baseLength + (baseLength * value / elementSize), minLength)); position = 0; } else if (value > maxScrollPosition) { length = round(max(baseLength - (baseLength * (value - maxScrollPosition) / elementSize), minLength)); position = maxPosition + baseLength - length; } else { position = round(value / maxScrollPosition * maxPosition); } me[names.translate](position); el[names.setLength](length); }, show: function() { var me = this, el = me.element, anim = el.getActiveAnimation(); if (anim) { anim.end(); } if (!me._inDom) { me.getScroller().getElement().appendChild(el); me._inDom = true; if (!me.size) { me.cacheStyles(); } } me.refreshLength(); clearTimeout(me._hideTimer); el.setStyle('opacity', ''); }, privates: { cacheStyles: function() { var me = this, el = me.element, names = me.names; me.size = el[names.getSize](); me.margin = el.getMargin(names.side); }, doHide: function() { var animation = this.getHideAnimation(), el = this.element; if (animation) { el.animate(animation); } else { el.setStyle('opacity', 0); } }, hasOpposite: function() { return this.getScroller().isAxisEnabled(this.oppositeAxis[this.getAxis()]); }, onHideAnimationEnd: function() { this.element.setStyle('opacity', '0'); }, refreshLength: function() { var me = this, names = me.names, axis = me.getAxis(), scroller = me.getScroller(), scrollSize = scroller.getSize()[axis], elementSize = scroller.getElementSize()[axis], ratio = elementSize / scrollSize, baseSizeAdjust = me.margin * 2, sizeAdjust = me.hasOpposite() ? (baseSizeAdjust + me.size) : baseSizeAdjust, length = Math.max(Math.round((elementSize - sizeAdjust) * ratio), me.getMinLength()); me.sizeAdjust = sizeAdjust; me.length = length; me.element[names.setLength](length); }, translateX: function(value) { this.element.translate(value); }, translateY: function(value) { this.element.translate(0, value); } } }); Ext.define('Ext.scroll.TouchScroller', { extend: 'Ext.scroll.Scroller', alias: 'scroller.touch', requires: [ 'Ext.fx.easing.BoundMomentum', 'Ext.fx.easing.EaseOut', 'Ext.util.Translatable', 'Ext.scroll.Indicator', 'Ext.GlobalEvents' ], isTouchScroller: true, config: { autoRefresh: true, bounceEasing: { duration: 400 }, elementSize: undefined, indicators: true, fps: 'auto', maxAbsoluteVelocity: 6, momentumEasing: { momentum: { acceleration: 30, friction: 0.5 }, bounce: { acceleration: 30, springTension: 0.3 }, minVelocity: 1 }, outOfBoundRestrictFactor: 0.5, innerElement: null, size: undefined, slotSnapEasing: { duration: 150 }, slotSnapSize: { x: 0, y: 0 }, slotSnapOffset: { x: 0, y: 0 }, startMomentumResetTime: 300, translatable: { translationMethod: 'auto', useWrapper: false } }, cls: Ext.baseCSSPrefix + 'scroll-container', scrollerCls: Ext.baseCSSPrefix + 'scroll-scroller', dragStartTime: 0, dragEndTime: 0, isDragging: false, isAnimating: false, isMouseEvent: { mousedown: 1, mousemove: 1, mouseup: 1 }, listenerMap: { touchstart: 'onTouchStart', touchmove: 'onTouchMove', dragstart: 'onDragStart', drag: 'onDrag', dragend: 'onDragEnd' }, refreshCounter: 0, constructor: function(config) { var me = this, onEvent = 'onEvent'; me.elementListeners = { touchstart: onEvent, touchmove: onEvent, dragstart: onEvent, drag: onEvent, dragend: onEvent, scope: me }; me.minPosition = { x: 0, y: 0 }; me.startPosition = { x: 0, y: 0 }; me.position = { x: 0, y: 0 }; me.velocity = { x: 0, y: 0 }; me.isAxisEnabledFlags = { x: false, y: false }; me.flickStartPosition = { x: 0, y: 0 }; me.flickStartTime = { x: 0, y: 0 }; me.lastDragPosition = { x: 0, y: 0 }; me.dragDirection = { x: 0, y: 0 }; Ext.GlobalEvents.on('idle', me.onIdle, me); me.callParent([ config ]); me.refreshAxes(); }, applyBounceEasing: function(easing) { var defaultClass = Ext.fx.easing.EaseOut; return { x: Ext.factory(easing, defaultClass), y: Ext.factory(easing, defaultClass) }; }, applyElementSize: function(size) { var el = this.getElement(), dom, x, y; if (!el) { return null; } dom = el.dom; if (!dom) { return; } if (size == null) { x = dom.clientWidth; y = dom.clientHeight; } else { x = size.x; y = size.y; } return { x: x, y: y }; }, applyIndicators: function(indicators, oldIndicators) { var me = this, xIndicator, yIndicator, x, y; if (indicators) { if (indicators === true) { xIndicator = yIndicator = {}; } else { x = indicators.x; y = indicators.y; if (x || y) { xIndicator = (x == null || x === true) ? {} : x; yIndicator = (x == null || y === true) ? {} : y; } else { xIndicator = yIndicator = indicators; } } if (oldIndicators) { if (xIndicator) { oldIndicators.x.setConfig(xIndicator); } else { oldIndicators.x.destroy(); oldIndicators.x = null; } if (yIndicator) { oldIndicators.y.setConfig(yIndicator); } else { oldIndicators.y.destroy(); oldIndicators.y = null; } indicators = oldIndicators; } else { indicators = { x: null, y: null }; if (xIndicator) { indicators.x = new Ext.scroll.Indicator(Ext.applyIf({ axis: 'x', scroller: me }, xIndicator)); } if (yIndicator) { indicators.y = new Ext.scroll.Indicator(Ext.applyIf({ axis: 'y', scroller: me }, yIndicator)); } } } else if (oldIndicators) { oldIndicators.x.destroy(); oldIndicators.y.destroy(); oldIndicators.x = null; oldIndicators.y = null; } return indicators; }, applyMomentumEasing: function(easing) { var defaultClass = Ext.fx.easing.BoundMomentum; return { x: Ext.factory(easing, defaultClass), y: Ext.factory(easing, defaultClass) }; }, applyInnerElement: function(innerElement) { if (innerElement && !innerElement.isElement) { innerElement = Ext.get(innerElement); } if (this.isConfiguring && !innerElement) { Ext.Error.raise("Cannot create Ext.scroll.TouchScroller instance with null innerElement"); } return innerElement; }, applySize: function(size) { var el, dom, scrollerDom, x, y; if (size == null) { el = this.getElement(); if (!el) { return null; } dom = el.dom; scrollerDom = this.getInnerElement().dom; x = Math.max(scrollerDom.scrollWidth, dom.clientWidth); y = Math.max(scrollerDom.scrollHeight, dom.clientHeight); } else if (typeof size === 'number') { x = size; y = size; } else { x = size.x; y = size.y; } return { x: x, y: y }; }, applySlotSnapOffset: function(snapOffset) { if (typeof snapOffset === 'number') { return { x: snapOffset, y: snapOffset }; } return snapOffset; }, applySlotSnapSize: function(snapSize) { if (typeof snapSize === 'number') { return { x: snapSize, y: snapSize }; } return snapSize; }, applySlotSnapEasing: function(easing) { var defaultClass = Ext.fx.easing.EaseOut; return { x: Ext.factory(easing, defaultClass), y: Ext.factory(easing, defaultClass) }; }, applyTranslatable: function(config, translatable) { return Ext.factory(config, Ext.util.Translatable, translatable); }, destroy: function() { var me = this, element = me.getElement(), innerElement = me.getInnerElement(), sizeMonitors = me.sizeMonitors; if (sizeMonitors) { sizeMonitors.element.destroy(); sizeMonitors.container.destroy(); } if (element && !element.isDestroyed) { element.removeCls(me.cls); } if (innerElement && !innerElement.isDestroyed) { innerElement.removeCls(me.scrollerCls); } if (me._isWrapped) { if (!element.isDestroyed) { me.unwrapContent(); } innerElement.destroy(); if (me.FixedHBoxStretching) { innerElement.parent().destroy(); } } me.setElement(null); me.setInnerElement(null); Ext.GlobalEvents.un('idle', me.onIdle, me); Ext.destroy(me.getTranslatable()); me.callParent(arguments); }, getPosition: function() { return this.position; }, refresh: function(immediate, options) { ++this.refreshCounter; if (immediate) { this.doRefresh(options); } }, updateAutoRefresh: function(autoRefresh) { this.toggleResizeListeners(autoRefresh); }, updateBounceEasing: function(easing) { this.getTranslatable().setEasingX(easing.x).setEasingY(easing.y); }, updateElementSize: function() { if (!this.isConfiguring) { this.refreshAxes(); } }, updateDisabled: function(disabled) { if (!this.isConfiguring) { if (disabled) { this.detachListeners(); } else { this.attachListeners(); } } }, updateElement: function(element, oldElement) { var me = this, innerElement = me.getInnerElement(), fixedHBoxStretching = this.FixedHBoxStretching, listeners; if (!innerElement) { innerElement = element.dom.firstChild; if (fixedHBoxStretching && innerElement) { innerElement = innerElement.dom.firstChild; } if (!innerElement || innerElement.nodeType !== 1 || !Ext.fly(innerElement).hasCls(me.scrollerCls)) { innerElement = me.wrapContent(element); } me.setInnerElement(innerElement); } if (!fixedHBoxStretching) { element.addCls(me.cls); } if (me.isConfiguring) { if (!me.getTranslatable().isScrollParent) { listeners = me.elementListeners; listeners.mousewheel = 'onMouseWheel'; listeners.scroll = { fn: 'onElementScroll', delegated: false, scope: me }; } } if (!me.getDisabled()) { me.attachListeners(); } if (!me.isConfiguring) { if (me.getAutoRefresh()) { me.toggleResizeListeners(true); } me.setSize(null); me.setElementSize(null); } me.callParent([ element, oldElement ]); }, updateFps: function(fps) { if (fps !== 'auto') { this.getTranslatable().setFps(fps); } }, updateMaxUserPosition: function() { this.snapToBoundary(); }, updateMinUserPosition: function() { this.snapToBoundary(); }, updateInnerElement: function(innerElement) { if (innerElement) { innerElement.addCls(this.scrollerCls); } this.getTranslatable().setElement(innerElement); }, updateSize: function() { if (!this.isConfiguring) { this.refreshAxes(); } }, updateTranslatable: function(translatable) { translatable.setElement(this.getInnerElement()); translatable.on({ animationframe: 'onAnimationFrame', animationend: 'onAnimationEnd', scope: this }); }, updateX: function() { if (!this.isConfiguring) { this.refreshAxes(); } }, updateY: function() { if (!this.isConfiguring) { this.refreshAxes(); } }, privates: { attachListeners: function() { this.getElement().on(this.elementListeners); }, constrainX: function(x) { return Math.min(this.getMaxPosition().x, Math.max(x, 0)); }, constrainY: function(y) { return Math.min(this.getMaxPosition().y, Math.max(y, 0)); }, convertEasingConfig: function(config) { return config; }, detachListeners: function() { this.getElement().un(this.elementListeners); }, doRefresh: function(options) { var me = this, size, elementSize; if (me.refreshCounter && me.getElement()) { me.stopAnimation(); me.getTranslatable().refresh(); if (options) { size = options.size; elementSize = options.elementSize; if (size) { me.setSize(size); } if (elementSize) { me.setElementSize(elementSize); } } else { me.setSize(null); me.setElementSize(null); } me.fireEvent('refresh', me); me.refreshCounter = 0; } }, doScrollTo: function(x, y, animation, allowOverscroll) { var me = this, isDragging = me.isDragging, fireScrollCallback; if (me.isDestroyed || !me.getElement()) { return me; } allowOverscroll = allowOverscroll || me.isDragging; var translatable = me.getTranslatable(), position = me.position, positionChanged = false, translationX, translationY; if (!isDragging || me.isAxisEnabled('x')) { if (isNaN(x) || typeof x !== 'number') { x = position.x; } else { if (!allowOverscroll) { x = me.constrainX(x); } if (position.x !== x) { position.x = x; positionChanged = true; } } translationX = me.convertX(-x); } if (!isDragging || me.isAxisEnabled('y')) { if (isNaN(y) || typeof y !== 'number') { y = position.y; } else { if (!allowOverscroll) { y = me.constrainY(y); } if (position.y !== y) { position.y = y; positionChanged = true; } } translationY = -y; } if (positionChanged) { if (animation) { fireScrollCallback = function() { me.onScroll(); }; if (animation === true) { animation = { callback: fireScrollCallback }; } else if (animation.callback) { animation.callback = Ext.Function.createSequence(animation.callback, fireScrollCallback); } else { animation.callback = fireScrollCallback; } translatable.translateAnimated(translationX, translationY, animation); } else { translatable.translate(translationX, translationY); me.onScroll(); } } return me; }, getAnimationEasing: function(axis, e) { if (!this.isAxisEnabled(axis)) { return null; } var me = this, currentPosition = me.position[axis], minPosition = me.getMinUserPosition()[axis], maxPosition = me.getMaxUserPosition()[axis], maxAbsVelocity = me.getMaxAbsoluteVelocity(), boundValue = null, dragEndTime = me.dragEndTime, velocity = e.flick.velocity[axis], isX = axis === 'x', easingConfig, easing; if (currentPosition < minPosition) { boundValue = minPosition; } else if (currentPosition > maxPosition) { boundValue = maxPosition; } if (isX) { currentPosition = me.convertX(currentPosition); boundValue = me.convertX(boundValue); } if (boundValue !== null) { easing = me.getBounceEasing()[axis]; easing.setConfig({ startTime: dragEndTime, startValue: -currentPosition, endValue: -boundValue }); return easing; } if (velocity === 0) { return null; } if (velocity < -maxAbsVelocity) { velocity = -maxAbsVelocity; } else if (velocity > maxAbsVelocity) { velocity = maxAbsVelocity; } if (Ext.browser.is.IE) { velocity *= 2; } easing = me.getMomentumEasing()[axis]; easingConfig = { startTime: dragEndTime, startValue: -currentPosition, startVelocity: velocity * 1.5, minMomentumValue: -maxPosition, maxMomentumValue: 0 }; if (isX) { me.convertEasingConfig(easingConfig); } easing.setConfig(easingConfig); return easing; }, getSnapPosition: function(axis) { var me = this, snapSize = me.getSlotSnapSize()[axis], snapPosition = null, position, snapOffset, maxPosition, mod; if (snapSize !== 0 && me.isAxisEnabled(axis)) { position = me.position[axis]; snapOffset = me.getSlotSnapOffset()[axis]; maxPosition = me.getMaxUserPosition()[axis]; mod = Math.floor((position - snapOffset) % snapSize); if (mod !== 0) { if (position !== maxPosition) { if (Math.abs(mod) > snapSize / 2) { snapPosition = Math.min(maxPosition, position + ((mod > 0) ? snapSize - mod : mod - snapSize)); } else { snapPosition = position - mod; } } else { snapPosition = position - mod; } } } return snapPosition; }, hideIndicators: function() { var me = this, indicators = me.getIndicators(), xIndicator, yIndicator; if (indicators) { if (me.isAxisEnabled('x')) { xIndicator = indicators.x; if (xIndicator) { xIndicator.hide(); } } if (me.isAxisEnabled('y')) { yIndicator = indicators.y; if (yIndicator) { yIndicator.hide(); } } } }, isAxisEnabled: function(axis) { this.getX(); this.getY(); return this.isAxisEnabledFlags[axis]; }, onAnimationEnd: function() { this.snapToBoundary(); this.onScrollEnd(); }, onAnimationFrame: function(translatable, x, y) { var position = this.position; position.x = this.convertX(-x); position.y = -y; this.onScroll(); }, onAxisDrag: function(axis, delta) { if (!this.isAxisEnabled(axis)) { return; } var me = this, flickStartPosition = me.flickStartPosition, flickStartTime = me.flickStartTime, lastDragPosition = me.lastDragPosition, dragDirection = me.dragDirection, old = me.position[axis], min = me.getMinUserPosition()[axis], max = me.getMaxUserPosition()[axis], start = me.startPosition[axis], last = lastDragPosition[axis], current = start - delta, lastDirection = dragDirection[axis], restrictFactor = me.getOutOfBoundRestrictFactor(), startMomentumResetTime = me.getStartMomentumResetTime(), now = Ext.Date.now(), distance; if (current < min) { current *= restrictFactor; } else if (current > max) { distance = current - max; current = max + distance * restrictFactor; } if (current > last) { dragDirection[axis] = 1; } else if (current < last) { dragDirection[axis] = -1; } if ((lastDirection !== 0 && (dragDirection[axis] !== lastDirection)) || (now - flickStartTime[axis]) > startMomentumResetTime) { flickStartPosition[axis] = old; flickStartTime[axis] = now; } lastDragPosition[axis] = current; }, onDomScroll: function() { var me = this, dom, position; if (me.getTranslatable().isScrollParent) { dom = me.getElement().dom; position = me.position; position.x = dom.scrollLeft; position.y = dom.scrollTop; } me.callParent(); }, onDrag: function(e) { var me = this, lastDragPosition = me.lastDragPosition; if (!me.isDragging) { return; } me.onAxisDrag('x', me.convertX(e.deltaX)); me.onAxisDrag('y', e.deltaY); me.doScrollTo(lastDragPosition.x, lastDragPosition.y); }, onDragEnd: function(e) { var me = this, easingX, easingY; if (!me.isDragging) { return; } me.dragEndTime = Ext.Date.now(); me.onDrag(e); me.isDragging = false; easingX = me.getAnimationEasing('x', e); easingY = me.getAnimationEasing('y', e); if (easingX || easingY) { me.getTranslatable().animate(easingX, easingY); } else { me.onScrollEnd(); } }, onDragStart: function(e) { var me = this, direction = me.getDirection(), absDeltaX = e.absDeltaX, absDeltaY = e.absDeltaY, directionLock = me.getDirectionLock(), startPosition = me.startPosition, flickStartPosition = me.flickStartPosition, flickStartTime = me.flickStartTime, lastDragPosition = me.lastDragPosition, currentPosition = me.position, dragDirection = me.dragDirection, x = currentPosition.x, y = currentPosition.y, now = Ext.Date.now(); me.isDragging = true; if (directionLock && direction !== 'both') { if ((direction === 'horizontal' && absDeltaX > absDeltaY) || (direction === 'vertical' && absDeltaY > absDeltaX)) { e.stopPropagation(); } else { me.isDragging = false; return; } } lastDragPosition.x = x; lastDragPosition.y = y; flickStartPosition.x = x; flickStartPosition.y = y; startPosition.x = x; startPosition.y = y; flickStartTime.x = now; flickStartTime.y = now; dragDirection.x = 0; dragDirection.y = 0; me.dragStartTime = now; me.isDragging = true; me.onScrollStart(); }, onElementResize: function(element, info) { this.refresh(true, { elementSize: { x: info.width, y: info.height } }); }, onElementScroll: function(event, targetEl) { targetEl.scrollTop = targetEl.scrollLeft = 0; }, onEvent: function(e) { var me = this, browserEvent = e.browserEvent; if ((!me.self.isTouching || me.isTouching) && ((!me.getTranslatable().isScrollParent) || (!me.isMouseEvent[browserEvent.type] && browserEvent.pointerType !== 'mouse')) && (me.getY() || me.getX())) { me[me.listenerMap[e.type]](e); } }, onIdle: function() { this.doRefresh(); }, onInnerElementResize: function(element, info) { this.refresh(true, { size: { x: info.width, y: info.height } }); }, onMouseWheel: function(e) { var me = this, delta = e.getWheelDeltas(), deltaX = -delta.x, deltaY = -delta.y, position = me.position, maxPosition = me.getMaxUserPosition(), minPosition = me.getMinUserPosition(), max = Math.max, min = Math.min, positionX = max(min(position.x + deltaX, maxPosition.x), minPosition.x), positionY = max(min(position.y + deltaY, maxPosition.y), minPosition.y); deltaX = positionX - position.x; deltaY = positionY - position.y; if (!deltaX && !deltaY) { return; } e.stopEvent(); me.onScrollStart(); me.scrollBy(deltaX, deltaY); me.onScroll(); me.onScrollEnd(); }, onPartnerScrollEnd: function() { this.hideIndicators(); }, onPartnerScrollStart: function() { this.showIndicators(); }, onScroll: function() { var me = this, position = me.position, x = position.x, y = position.y, indicators = me.getIndicators(), xIndicator, yIndicator; if (indicators) { if (me.isAxisEnabled('x')) { xIndicator = indicators.x; if (xIndicator) { xIndicator.setValue(x); } } if (me.isAxisEnabled('y')) { yIndicator = indicators.y; if (yIndicator) { yIndicator.setValue(y); } } } me.fireScroll(x, y); }, onScrollEnd: function() { var me = this, position = me.position; if (!me.isTouching && !me.snapToSlot()) { me.hideIndicators(); Ext.isScrolling = false; me.fireScrollEnd(position.x, position.y); } }, onScrollStart: function() { var me = this, position = me.position; me.showIndicators(); Ext.isScrolling = true; me.fireScrollStart(position.x, position.y); }, onTouchEnd: function() { var me = this; me.isTouching = me.self.isTouching = false; if (!me.isDragging && me.snapToSlot()) { me.onScrollStart(); } }, onTouchMove: function(e) { e.preventDefault(); }, onTouchStart: function() { var me = this; me.isTouching = me.self.isTouching = true; Ext.getDoc().on({ touchend: 'onTouchEnd', scope: me, single: true }); me.stopAnimation(); }, refreshAxes: function() { var me = this, flags = me.isAxisEnabledFlags, size = me.getSize(), elementSize = me.getElementSize(), indicators = me.getIndicators(), maxX, maxY, x, y, xIndicator, yIndicator; if (!size || !elementSize) { return; } maxX = Math.max(0, size.x - elementSize.x); maxY = Math.max(0, size.y - elementSize.y); x = me.getX(); y = me.getY(); me.setMaxPosition({ x: maxX, y: maxY }); if (x === true || x === 'auto') { flags.x = !!maxX; } else if (x === false) { flags.x = false; xIndicator = indicators && indicators.x; if (xIndicator) { xIndicator.hide(); } } else if (x === 'scroll') { flags.x = true; } if (y === true || y === 'auto') { flags.y = !!maxY; } else if (y === false) { flags.y = false; yIndicator = indicators && indicators.y; if (yIndicator) { yIndicator.hide(); } } else if (y === 'scroll') { flags.y = true; } me.setMaxUserPosition({ x: flags.x ? maxX : 0, y: flags.y ? maxY : 0 }); if (Ext.supports.touchScroll === 1) { me.initXStyle(); me.initYStyle(); } }, showIndicators: function() { var me = this, indicators = me.getIndicators(), xIndicator, yIndicator; if (indicators) { if (me.isAxisEnabled('x')) { xIndicator = indicators.x; if (xIndicator) { xIndicator.show(); } } if (me.isAxisEnabled('y')) { yIndicator = indicators.y; if (yIndicator) { yIndicator.show(); } } } }, snapToBoundary: function() { if (this.isConfiguring) { return; } var me = this, position = me.position, minPosition = me.getMinUserPosition(), maxPosition = me.getMaxUserPosition(), minX = minPosition.x, minY = minPosition.y, maxX = maxPosition.x, maxY = maxPosition.y, x = Math.round(position.x), y = Math.round(position.y); if (x < minX) { x = minX; } else if (x > maxX) { x = maxX; } if (y < minY) { y = minY; } else if (y > maxY) { y = maxY; } me.doScrollTo(x, y); }, snapToSlot: function() { var me = this, snapX = me.getSnapPosition('x'), snapY = me.getSnapPosition('y'), easing = me.getSlotSnapEasing(); if (snapX !== null || snapY !== null) { me.doScrollTo(snapX, snapY, { easingX: easing.x, easingY: easing.y }); return true; } return false; }, stopAnimation: function() { this.getTranslatable().stopAnimation(); }, toggleResizeListeners: function(on) { var me = this, element = me.getElement(), method = on ? 'on' : 'un'; if (element) { element[method]('resize', 'onElementResize', me); me.getInnerElement()[method]('resize', 'onInnerElementResize', me); } }, unwrapContent: function() { var innerDom = this.getInnerElement().dom, dom = this.getElement().dom, child; while ((child = innerDom.firstChild)) { dom.insertBefore(child, innerDom); } }, wrapContent: function(element) { var wrap = document.createElement('div'), dom = element.dom, child; while (child = dom.lastChild) { wrap.insertBefore(child, wrap.firstChild); } dom.appendChild(wrap); this.setInnerElement(wrap); this._isWrapped = true; return this.getInnerElement(); } } }); Ext.define('Ext.scroll.DomScroller', { extend: 'Ext.scroll.Scroller', alias: 'scroller.dom', isDomScroller: true, getMaxPosition: function() { var element = this.getElement(), x = 0, y = 0, dom; if (element && !element.isDestroyed) { dom = element.dom; x = dom.scrollWidth - dom.clientWidth; y = dom.scrollHeight - dom.clientHeight; } return { x: x, y: y }; }, getMaxUserPosition: function() { var me = this, element = me.getElement(), x = 0, y = 0, dom; if (element && !element.isDestroyed) { dom = element.dom; if (me.getX()) { x = dom.scrollWidth - dom.clientWidth; } if (me.getY()) { y = dom.scrollHeight - dom.clientHeight; } } return { x: x, y: y }; }, getPosition: function() { var element = this.getElement(), x = 0, y = 0, position; if (element && !element.isDestroyed) { position = this.getElementScroll(element); x = position.left; y = position.top; } return { x: x, y: y }; }, getSize: function() { var element = this.getElement(), size, dom; if (element && !element.isDestroyed) { dom = element.dom; size = { x: dom.scrollWidth, y: dom.scrollHeight }; } else { size = { x: 0, y: 0 }; } return size; }, setSize: Ext.emptyFn, updateElement: function(element, oldElement) { this.initXStyle(); this.initYStyle(); this.callParent([ element, oldElement ]); }, updateX: function(x) { this.initXStyle(); }, updateY: function(y) { this.initYStyle(); }, privates: { doScrollTo: function(x, y, animate) { var me = this, element = me.getElement(), maxPosition, dom, to, xInf, yInf; if (element && !element.isDestroyed) { dom = this.getElement().dom; xInf = (x === Infinity); yInf = (y === Infinity); if (xInf || yInf) { maxPosition = me.getMaxPosition(); if (xInf) { x = maxPosition.x; } if (yInf) { y = maxPosition.y; } } x = me.convertX(x); if (animate) { to = {}; if (y != null) { to.scrollTop = y; } if (x != null) { to.scrollLeft = x; } element.animate(Ext.mergeIf({ to: { scrollTop: y, scrollLeft: x } }, animate)); } else { if (y != null) { dom.scrollTop = y; } if (x != null) { dom.scrollLeft = x; } } } }, getElementScroll: function(element) { return element.getScroll(); }, stopAnimation: function() { var anim = this.getElement().getActiveAnimation(); if (anim) { anim.end(); } } } }); Ext.define('Ext.util.Floating', { mixinId: 'floating', uses: [ 'Ext.ZIndexManager' ], focusOnToFront: true, shadow: 'sides', animateShadow: false, constrain: false, config: { activeCounter: 0, alwaysOnTop: false }, preventDefaultAlign: false, _visModeMap: { visibility: 1, display: 2, offsets: 3 }, constructor: function() { var me = this, el = me.el, shadow = me.shadow, shadowOffset, shadowConfig; if (shadow) { shadowConfig = { mode: (shadow === true) ? 'sides' : shadow }; shadowOffset = me.shadowOffset; if (shadowOffset) { shadowConfig.offset = shadowOffset; } shadowConfig.animate = me.animateShadow; shadowConfig.fixed = me.fixed; el.enableShadow(shadowConfig, false); } if (me.shim || Ext.useShims) { el.enableShim({ fixed: me.fixed }, false); } el.setVisibilityMode(me._visModeMap[me.hideMode]); if (me.modal && !(Ext.enableFocusManager)) { me.el.on('keydown', me.onKeyDown, me); } me.el.on({ mousedown: me.onMouseDown, scope: me, capture: true }); me.registerWithOwnerCt(); me.initHierarchyEvents(); }, alignTo: function(element, position, offsets, animate) { var me = this; if (!me._lastAlignToEl) { Ext.on('scroll', me.onAlignToScroll, me); } me._lastAlignToEl = element; me._lastAlignToPos = position; me.mixins.positionable.alignTo.call(me, element, position, offsets, animate); }, initFloatConstrain: function() { var me = this, floatParent = me.floatParent; if ((me.constrain || me.constrainHeader) && !me.constrainTo) { me.constrainTo = floatParent ? floatParent.getTargetEl() : me.container; } }, initHierarchyEvents: function() { var me = this, syncHidden = this.syncHidden; if (!me.hasHierarchyEventListeners) { me.mon(Ext.GlobalEvents, { hide: syncHidden, collapse: syncHidden, show: syncHidden, expand: syncHidden, added: syncHidden, scope: me }); me.hasHierarchyEventListeners = true; } }, registerWithOwnerCt: function() { var me = this, ownerCt = me.ownerCt, zip = me.zIndexParent; if (zip) { zip.unregisterFloatingItem(me); } zip = me.zIndexParent = me.up('[floating]'); me.floatParent = ownerCt || zip; me.initFloatConstrain(); delete me.ownerCt; if (zip) { zip.registerFloatingItem(me); } else { Ext.WindowManager.register(me); } }, onKeyDown: function(e) { var me = this, shift, focusables, first, last; if (e.getKey() === e.TAB) { shift = e.shiftKey; focusables = me.query(':focusable'); if (focusables.length) { first = focusables[0]; last = focusables[focusables.length - 1]; if (!shift && last.hasFocus) { e.stopEvent(); first.focus(); } else if (shift && first.hasFocus) { e.stopEvent(); last.focus(); } } } }, onMouseDown: function(e) { var me = this, focusTask = me.focusTask, parentEvent = e.parentEvent, preventFocus = parentEvent && parentEvent.type === 'touchstart', target, dom, skipFronting; if (me.floating && (!focusTask || !focusTask.id)) { target = e.target; dom = me.el.dom; while (!preventFocus && target && target !== dom) { if (Ext.fly(target).isFocusable()) { preventFocus = true; } target = target.parentNode; } skipFronting = Ext.WindowManager.getActive() === me && (target === dom || preventFocus); if (!skipFronting) { me.toFront(preventFocus); } } }, onBeforeFloatLayout: function() { this.el.preventSync = true; }, onAfterFloatLayout: function() { var el = this.el; if (el.shadow || el.shim) { el.setUnderlaysVisible(true); el.syncUnderlays(); } }, syncHidden: function() { var me = this, hidden = me.hidden || !me.rendered, hierarchicallyHidden = me.hierarchicallyHidden = me.isHierarchicallyHidden(), pendingShow = me.pendingShow; if (hidden !== hierarchicallyHidden) { if (hierarchicallyHidden) { me.hide(); me.pendingShow = true; } else if (pendingShow) { delete me.pendingShow; if (pendingShow.length) { me.show.apply(me, pendingShow); } else { me.show(); } } } }, setZIndex: function(index) { var me = this; me.el.setZIndex(index); index += 10; if (me.floatingDescendants) { index = Math.floor(me.floatingDescendants.setBase(index) / 100) * 100 + 10000; } return index; }, doConstrain: function(constrainTo) { var me = this, xy = me.calculateConstrainedPosition(constrainTo, null, true); if (xy) { me.setPosition(xy); } }, updateActiveCounter: function(activeCounter) { var zim = this.zIndexParent; if (zim && this.bringParentToFront !== false) { zim.setActiveCounter(++Ext.ZIndexManager.activeCounter); } zim = this.zIndexManager; if (zim) { zim.onComponentUpdate(this); } }, updateAlwaysOnTop: function(alwaysOnTop) { var z = this.zIndexManager; if (z) { z.onComponentUpdate(this); } }, toFront: function(preventFocus) { var me = this; if (me.zIndexManager.bringToFront(me, preventFocus || !me.focusOnToFront)) { if (me.hasListeners.tofront) { me.fireEvent('tofront', me, me.el.getZIndex()); } } return me; }, setActive: function(active, doFocus) { var me = this, activeCmp; if (active) { if (me.el.shadow && !me.maximized) { me.el.enableShadow(null, true); } if (doFocus) { activeCmp = Ext.ComponentManager.getActiveComponent(); if (!activeCmp || !activeCmp.up(me)) { me.focus(); } } me.fireEvent('activate', me); } else { me.fireEvent('deactivate', me); } }, toBack: function() { this.zIndexManager.sendToBack(this); return this; }, center: function() { var me = this, xy; if (me.isVisible()) { xy = me.getAlignToXY(me.container, 'c-c'); me.setPagePosition(xy); } else { me.needsCenter = true; } return me; }, onFloatShow: function() { if (this.needsCenter) { this.center(); } delete this.needsCenter; if (this.toFrontOnShow) { this.toFront(); } }, fitContainer: function(animate) { var me = this, parent = me.floatParent, container = parent ? parent.getTargetEl() : me.container, newBox = container.getViewSize(), newPosition = parent || (container.dom !== document.body) ? [ 0, 0 ] : container.getXY(); newBox.x = newPosition[0]; newBox.y = newPosition[1]; me.setBox(newBox, animate); }, privates: { onFloatDestroy: function() { this.clearAlignEl(); }, clearAlignEl: function() { var me = this; if (me._lastAlignToEl) { Ext.un('scroll', me.onAlignToScroll, me); me._lastAlignPos = me._lastAlignToEl = null; } }, onAlignToScroll: function(scroller) { var me = this, el = me._lastAlignToEl, dom; if (el && !scroller.getElement().contains(me.el)) { dom = el.isElement ? el.dom : el; if (dom && !Ext.isGarbage(dom)) { me.alignTo(el, me._lastAlignToPos); } else { me.clearAlignEl(); } } } } }); Ext.define('Ext.util.ElementContainer', { mixinId: 'elementCt', config: { childEls: { $value: {}, cached: true, lazy: true, merge: function(newValue, oldValue, target, mixinClass) { var childEls = oldValue ? Ext.Object.chain(oldValue) : {}, i, val; if (newValue instanceof Array) { for (i = newValue.length; i--; ) { val = newValue[i]; if (!mixinClass || !(val in childEls)) { if (typeof val === 'string') { childEls[val] = { name: val, itemId: val }; } else { childEls[val.name] = val; } } } } else if (newValue) { if (newValue.constructor === Object) { for (i in newValue) { if (!mixinClass || !(i in childEls)) { val = newValue[i]; if (val === true) { childEls[i] = { itemId: i }; } else if (typeof val === 'string') { childEls[i] = { itemId: val }; } else { childEls[i] = val; if (!('itemId' in val)) { val.itemId = i; } } childEls[i].name = i; } } } else { if (!mixinClass || !(newValue in childEls)) { childEls[newValue] = { name: newValue, itemId: newValue }; } } } return childEls; } } }, destroy: function() { var me = this, childEls = me.getChildEls(), child, childName; for (childName in childEls) { child = me[childName]; if (child) { if (child.destroy) { child.component = null; child.destroy(); } me[childName] = null; } } }, privates: { afterClassMixedIn: function(targetClass) { var proto = targetClass.prototype, childEls = proto.childEls; if (childEls) { delete proto.childEls; targetClass.getConfigurator().add({ childEls: childEls }); } }, attachChildEls: function(el, owner) { var me = this, childEls = me.getChildEls(), comp = owner || me, baseId = comp.id + '-', unframed = !comp.frame, childName, elements, entry, k, selector, value, id; for (childName in childEls) { entry = childEls[childName]; if (unframed && entry.frame) { continue; } selector = entry.select; if (selector) { value = el.select(selector, true); } else if (!(selector = entry.selectNode)) { if (!(id = entry.id)) { id = baseId + entry.itemId; value = Ext.cache[id]; } else { value = Ext.cache[id] || el.getById(id); } } else { value = el.selectNode(selector, false); } if (value) { if (value.isElement) { value.component = comp; } else if (value.isComposite && !value.isLite) { elements = value.elements; for (k = elements.length; k--; ) { elements[k].component = comp; } } } me[childName] = value || null; } } } }); Ext.define('Ext.util.Renderable', { mixinId: 'renderable', requires: [ 'Ext.dom.Element' ], frameCls: Ext.baseCSSPrefix + 'frame', frameIdRegex: /[\-]frame\d+[TMB][LCR]$/, frameElNames: [ 'TL', 'TC', 'TR', 'ML', 'MC', 'MR', 'BL', 'BC', 'BR', 'Table' ], frameTpl: [ '{%this.renderDockedItems(out,values,0);%}', '', '
{parent.baseCls}-{parent.ui}-{.}-tl{frameElCls}" role="presentation">', '
{parent.baseCls}-{parent.ui}-{.}-tr{frameElCls}" role="presentation">', '
{parent.baseCls}-{parent.ui}-{.}-tc{frameElCls}" role="presentation">
', '
', '
', '
', '
{parent.baseCls}-{parent.ui}-{.}-ml{frameElCls}" role="presentation">', '
{parent.baseCls}-{parent.ui}-{.}-mr{frameElCls}" role="presentation">', '
{parent.baseCls}-{parent.ui}-{.}-mc{frameElCls}" role="presentation">', '{%this.applyRenderTpl(out, values)%}', '
', '
', '
', '', '
{parent.baseCls}-{parent.ui}-{.}-bl{frameElCls}" role="presentation">', '
{parent.baseCls}-{parent.ui}-{.}-br{frameElCls}" role="presentation">', '
{parent.baseCls}-{parent.ui}-{.}-bc{frameElCls}" role="presentation">
', '
', '
', '
', '{%this.renderDockedItems(out,values,1);%}' ], frameTableTpl: [ '{%this.renderDockedItems(out,values,0);%}', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '{%this.renderDockedItems(out,values,1);%}' ], _renderState: 0, _layerCls: Ext.baseCSSPrefix + 'layer', _fixedLayerCls: Ext.baseCSSPrefix + 'fixed-layer', statics: { makeRenderSetter: function(cfg, renderState) { var name = cfg.name; return function(value) { var me = this, bucket = (me.renderConfigs || (me.renderConfigs = {})), pending = bucket[renderState]; if (me._renderState >= renderState) { (cfg.setter || cfg.getSetter()).call(me, value); } else { if (!pending) { bucket[renderState] = pending = {}; } if (!(name in pending)) { pending[name] = me[name]; } me[name] = value; } return me; }; }, processRenderConfig: function(source, configName, state) { var proto = this.prototype, configurator = this.getConfigurator(), Renderable = Ext.util.Renderable, makeSetter = Renderable.makeRenderSetter, renderConfig = source[configName], cachedSetter, cfg, name, setterName; for (name in renderConfig) { cfg = Ext.Config.get(name); if (!proto[setterName = cfg.names.set]) { cachedSetter = (cfg.renderSetter || (cfg.renderSetter = {})); proto[setterName] = cachedSetter[state] || (cachedSetter[state] = makeSetter(cfg, state)); } } delete source[configName]; configurator.add(renderConfig); } }, onClassMixedIn: function(targetClass) { var override = targetClass.override, processRenderConfig = this.processRenderConfig, processOverride = function(body) { if (body.beforeRenderConfig) { this.processRenderConfig(body, 'beforeRenderConfig', 1); } if (body.renderConfig) { this.processRenderConfig(body, 'renderConfig', 3); } override.call(this, body); }, processClass = function(theClass, classBody) { theClass.override = processOverride; theClass.processRenderConfig = processRenderConfig; if (classBody.beforeRenderConfig) { theClass.processRenderConfig(classBody, 'beforeRenderConfig', 1); } if (classBody.renderConfig) { theClass.processRenderConfig(classBody, 'renderConfig', 3); } }; processClass(targetClass, targetClass.prototype); targetClass.onExtended(processClass); }, afterRender: function() { var me = this, data = {}, protoEl = me.protoEl, target = me.el, controller, item, pre, hidden, contentEl; me.finishRenderChildren(); me._renderState = 4; if (me.contentEl) { pre = Ext.baseCSSPrefix; hidden = pre + 'hidden-'; contentEl = me.contentEl = Ext.get(me.contentEl); contentEl.component = me; contentEl.removeCls([ pre + 'hidden', hidden + 'display', hidden + 'offsets' ]); me.getContentTarget().appendChild(contentEl.dom); } protoEl.writeTo(data); item = data.removed; if (item) { target.removeCls(item); } item = data.cls; if (item.length) { target.addCls(item); } item = data.style; if (data.style) { target.setStyle(item); } me.protoEl = null; if (!me.ownerCt) { me.updateLayout(); } if (!(me.x && me.y) && (me.pageX || me.pageY)) { me.setPagePosition(me.pageX, me.pageY); } if (me.disableOnRender) { me.onDisable(); } if (Ext.enableAria) { me.ariaApplyAfterRenderAttributes(); } controller = me.controller; if (controller && controller.afterRender) { controller.afterRender(me); } }, afterFirstLayout: function(width, height) { var me = this, x = me.x, y = me.y, alignSpec = me.defaultAlign, alignOffset = me.alignOffset, controller, hasX, hasY, pos, xy; if (!me.ownerLayout) { hasX = x !== undefined; hasY = y !== undefined; } if (me.floating && !me.preventDefaultAlign && (!hasX || !hasY)) { if (me.floatParent) { pos = me.floatParent.getTargetEl().getViewRegion(); xy = me.el.getAlignToXY(me.alignTarget || me.floatParent.getTargetEl(), alignSpec, alignOffset); pos.x = xy[0] - pos.x; pos.y = xy[1] - pos.y; } else { xy = me.el.getAlignToXY(me.alignTarget || me.container, alignSpec, alignOffset); pos = me.el.translateXY(xy[0], xy[1]); } x = hasX ? x : pos.x; y = hasY ? y : pos.y; hasX = hasY = true; } if (hasX || hasY) { me.setPosition(x, y); } me.onBoxReady(width, height); controller = me.controller; if (controller && controller.boxReady) { controller.boxReady(me); } }, beforeRender: function() { var me = this, floating = me.floating, layout = me.getComponentLayout(), cls, controller; me._renderState = 1; controller = me.controller; if (controller && controller.beforeRender) { controller.beforeRender(me); } me.initBindable(); if (me.renderConfigs) { me.flushRenderConfigs(); } if (me.reference) { me.publishState(); } if (floating) { me.addCls(me.fixed ? me._fixedLayerCls : me._layerCls); cls = floating.cls; if (cls) { me.addCls(cls); } } me.frame = me.frame || me.alwaysFramed; if (!layout.initialized) { layout.initLayout(); } me.initOverflow(); me.setUI(me.ui); }, doApplyRenderTpl: function(out, values) { var me = values.$comp, tpl; if (!me.rendered) { tpl = me.initRenderTpl(); tpl.applyOut(values.renderData, out); } }, getElConfig: function() { var me = this, autoEl = me.autoEl, frameInfo = me.getFrameInfo(), config = { tag: 'div', tpl: frameInfo ? me.initFramingTpl(frameInfo.table) : me.initRenderTpl() }, layoutTargetCls = me.layoutTargetCls, protoEl = me.protoEl, frameData; me.initStyles(protoEl); if (layoutTargetCls && !frameInfo) { protoEl.addCls(layoutTargetCls); } protoEl.writeTo(config); protoEl.flush(); if (Ext.isString(autoEl)) { config.tag = autoEl; } else { Ext.apply(config, autoEl); } if (Ext.enableAria && me.ariaRenderAttributesToElement) { Ext.apply(config, me.ariaGetRenderAttributes()); } config.id = me.id; if (config.tpl) { if (frameInfo) { config.tplData = frameData = me.getFrameRenderData(); frameData.renderData = me.initRenderData(); } else { config.tplData = me.initRenderData(); } } return config; }, getInsertPosition: function(position) { if (position !== undefined) { if (Ext.isNumber(position)) { position = this.container.dom.childNodes[position]; } else { position = Ext.getDom(position); } } return position; }, getRenderTree: function() { var me = this, ret = null; if (!me.hasListeners.beforerender || me.fireEvent('beforerender', me) !== false) { me._renderState = 1; me.beforeRender(); me.rendering = true; me._renderState = 2; ret = me.getElConfig(); if (me.el) { ret.id = me.$pid = Ext.id(null, me.el.identifiablePrefix); } } return ret; }, initRenderData: function() { var me = this; return Ext.apply({ $comp: me, id: me.id, ui: me.ui, uiCls: me.uiCls, baseCls: me.baseCls, componentCls: me.componentCls, frame: me.frame, renderScroller: me.touchScroll, scrollerCls: me.scrollerCls, role: me.ariaRole, childElCls: '' }, me.renderData); }, onRender: function(parentNode, containerIdx) { var me = this, x = me.x, y = me.y, lastBox = null, el = me.el, width, height; me.applyRenderSelectors(); me.rendering = null; me.rendered = true; me._renderState = 3; if (me.renderConfigs) { me.flushRenderConfigs(); } if (x != null) { lastBox = { x: x }; } if (y != null) { (lastBox = lastBox || {}).y = y; } if (!me.getFrameInfo()) { width = me.width; height = me.height; if (typeof width === 'number') { lastBox = lastBox || {}; lastBox.width = width; } if (typeof height === 'number') { lastBox = lastBox || {}; lastBox.height = height; } } if (me.touchScroll === 1) { me.getOverflowEl().disableTouchScroll(); } me.lastBox = el.lastBox = lastBox; }, render: function(container, position) { var me = this, el = me.el, ownerLayout = me.ownerLayout, vetoed, tree, nextSibling; if (el && !el.isElement) { me.wrapPrimaryEl(el); el = me.el; } Ext.suspendLayouts(); container = me.initContainer(container); nextSibling = me.getInsertPosition(position); if (!el) { tree = me.getRenderTree(); if (ownerLayout && ownerLayout.transformItemRenderTree) { tree = ownerLayout.transformItemRenderTree(tree); } if (tree) { if (nextSibling) { el = Ext.DomHelper.insertBefore(nextSibling, tree); } else { el = Ext.DomHelper.append(container, tree); } me.wrapPrimaryEl(el); me.cacheRefEls(el); } } else { if (!me.hasListeners.beforerender || me.fireEvent('beforerender', me) !== false) { me.beforeRender(); me.needsRenderTpl = me.rendering = true; me._renderState = 2; me.initStyles(el); if (me.allowDomMove !== false) { if (nextSibling) { container.dom.insertBefore(el.dom, nextSibling); } else { container.dom.appendChild(el.dom); } } } else { vetoed = true; } } if (el && !vetoed) { me.finishRender(position); } Ext.resumeLayouts(!me.hidden && !container.isDetachedBody); }, ensureAttachedToBody: function(runLayout) { var comp = this, body; while (comp.ownerCt) { comp = comp.ownerCt; } if (comp.container.isDetachedBody) { comp.container = body = Ext.getBody(); body.appendChild(comp.el.dom); if (runLayout) { comp.updateLayout(); } if (typeof comp.x === 'number' || typeof comp.y === 'number') { comp.setPosition(comp.x, comp.y); } } }, privates: { applyRenderSelectors: function() { var me = this, selectors = me.renderSelectors, el = me.el, query, selector; me.attachChildEls(el); if (selectors) { for (selector in selectors) { query = selectors[selector]; if (query) { me[selector] = el.selectNode(query, false); } } } }, cacheRefEls: function(el) { el = el || this.el; var cache = Ext.cache, El = Ext.dom.Element, dom = el.isElement ? el.dom : el, refs = dom.querySelectorAll('[data-ref]'), len = refs.length, ref, i; for (i = 0; i < len; i++) { ref = refs[i]; if (!cache[ref.id]) { new El(ref); } } }, doAutoRender: function() { var me = this; if (!me.rendered) { if (me.floating) { me.render(me.renderTo || document.body); } else { me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender); } } }, doRenderContent: function(out, renderData) { var me = renderData.$comp, data = me.data; if (me.html) { Ext.DomHelper.generateMarkup(me.html, out); delete me.html; } if (me.tpl) { if (!me.tpl.isTemplate) { me.tpl = new Ext.XTemplate(me.tpl); } if (data) { me.data = data = data.isEntity ? data.getData(true) : data; me.tpl.applyOut(data, out); } } }, doRenderFramingDockedItems: function(out, renderData, after) { var me = renderData.$comp; if (!me.rendered && me.doRenderDockedItems) { renderData.renderData.$skipDockedItems = true; me.doRenderDockedItems.call(this, out, renderData, after); } }, flushRenderConfigs: function() { var me = this, configs = me.renderConfigs, state = me._renderState, bucket, i, name, newConfigs, value; if (configs) { for (i = 0; i <= state; ++i) { bucket = configs[i]; if (bucket) { configs[i] = null; for (name in bucket) { value = bucket[name]; (newConfigs || (newConfigs = {}))[name] = me[name]; me[name] = value; } } } if (newConfigs) { me.setConfig(newConfigs); } } }, finishRender: function(containerIdx) { var me = this, cache = Ext.cache, proxy, first, id, tpl, data, dom, el; if (!me.el || me.$pid) { if (me.container) { el = cache[me.id]; dom = el ? el.dom : me.container.getById(me.id, true); } else { id = me.$pid || me.id; el = cache[id]; dom = el ? el.dom : Ext.getDom(id); } if (!me.el) { me.wrapPrimaryEl(dom); } else { delete me.$pid; if (!me.el.dom) { me.wrapPrimaryEl(me.el); } dom.parentNode.insertBefore(me.el.dom, dom); proxy = dom; dom = me.el.dom; first = dom.firstChild; while (proxy.firstChild) { dom.insertBefore(proxy.firstChild, first); } me.el.addCls(proxy.className); Ext.removeNode(proxy); } } else if (me.needsRenderTpl) { tpl = me.initRenderTpl(); if (tpl) { data = me.initRenderData(); tpl.insertFirst(me.getTargetEl(), data); } me.cacheRefEls(); } me.el.component = me; if (!me.container) { me.container = Ext.get(me.el.dom.parentNode); } if (me.ctCls) { me.container.addCls(me.ctCls); } me.onRender(me.container, containerIdx); if (!me.overflowInited) { me.initOverflow(); } me.el.setVisibilityMode(Ext.Element[me.hideMode.toUpperCase()]); if (me.overCls) { me.el.hover(me.addOverCls, me.removeOverCls, me); } if (me.hasListeners.render) { me.fireEvent('render', me); } me.afterRender(); if (me.hasListeners.afterrender) { me.fireEvent('afterrender', me); } me.initEvents(); if (me.hidden) { me.el.hide(); } }, finishRenderChildren: function() { var layout = this.getComponentLayout(); layout.finishRender(); }, getFrameRenderData: function() { var me = this, frameInfo = me.frameSize, mcStyle = ''; if (me._syncFrameHeight && me.height) { mcStyle = 'height:' + (me.height - frameInfo.height) + 'px'; } return { $comp: me, fgid: me.id + '-frame', ui: me.ui, uiCls: me.uiCls, frameCls: me.frameCls, frameBodyCls: me.layoutTargetCls || '', baseCls: me.baseCls, top: !!frameInfo.top, left: !!frameInfo.left, right: !!frameInfo.right, bottom: !!frameInfo.bottom, mcStyle: mcStyle, frameElCls: '' }; }, getFrameInfo: function() { if (Ext.supports.CSS3BorderRadius || !this.frame) { return false; } var me = this, frameInfoCache = me.frameInfoCache, cls = me.getFramingInfoCls() + '-frameInfo', frameInfo = frameInfoCache[cls], styleEl, info, frameTop, frameRight, frameBottom, frameLeft, borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth, paddingTop, paddingRight, paddingBottom, paddingLeft; if (frameInfo == null) { styleEl = Ext.fly(me.getStyleProxy(cls), 'frame-style-el'); info = styleEl.getStyle('font-family'); if (info) { info = info.split('-'); frameTop = parseInt(info[1], 10); frameRight = parseInt(info[2], 10); frameBottom = parseInt(info[3], 10); frameLeft = parseInt(info[4], 10); borderTopWidth = parseInt(info[5], 10); borderRightWidth = parseInt(info[6], 10); borderBottomWidth = parseInt(info[7], 10); borderLeftWidth = parseInt(info[8], 10); paddingTop = parseInt(info[9], 10); paddingRight = parseInt(info[10], 10); paddingBottom = parseInt(info[11], 10); paddingLeft = parseInt(info[12], 10); frameInfo = { table: info[0].charAt(0) === 't', vertical: info[0].charAt(1) === 'v', top: frameTop, right: frameRight, bottom: frameBottom, left: frameLeft, width: frameLeft + frameRight, height: frameTop + frameBottom, border: { top: borderTopWidth, right: borderRightWidth, bottom: borderBottomWidth, left: borderLeftWidth, width: borderLeftWidth + borderRightWidth, height: borderTopWidth + borderBottomWidth }, padding: { top: paddingTop, right: paddingRight, bottom: paddingBottom, left: paddingLeft, width: paddingLeft + paddingRight, height: paddingTop + paddingBottom } }; } else { frameInfo = false; } if (me.frame === true && !frameInfo) { Ext.log.error('You have set frame: true explicity on this component (' + me.getXType() + ') and it ' + 'does not have any framing defined in the CSS template. In this case IE cannot figure out ' + 'what sizes to use and thus framing on this component will be disabled.'); } frameInfoCache[cls] = frameInfo; } me.frame = !!frameInfo; me.frameSize = frameInfo; return frameInfo; }, getFramingInfoCls: function() { return this.baseCls + '-' + this.ui; }, getStyleProxy: function(cls) { var result = this.styleProxyEl || (Ext.Component.prototype.styleProxyEl = Ext.getBody().createChild({ 'data-sticky': true, role: 'presentation', style: { position: 'absolute', top: '-10000px' } }, null, true)); result.className = cls; return result; }, getFrameTpl: function(table) { return this.getTpl(table ? 'frameTableTpl' : 'frameTpl'); }, initContainer: function(container) { var me = this; if (!container && me.el) { container = me.el.dom.parentNode; me.allowDomMove = false; } me.container = container.dom ? container : Ext.get(container); return me.container; }, initOverflow: function() { var me = this, overflowStyle = me.getOverflowStyle(), scrollFlags = me.scrollFlags, overflowEl = me.getOverflowEl(), hasOverflow = (scrollFlags.y || scrollFlags.x), touchScroll = me.touchScroll = (hasOverflow && Ext.supports.touchScroll); if (!hasOverflow || !overflowEl || !overflowEl.isElement) { return; } me.overflowInited = true; if (touchScroll === 2) { overflowEl.setStyle('overflow', 'hidden'); } else { overflowEl.setStyle(overflowStyle); } }, doRenderPadding: function(out, renderData) { var me = renderData.$comp; if (me.touchScroll) { out.push('padding:', me.unitizeBox(me.padding)); } }, initFramingTpl: function(table) { var tpl = this.getFrameTpl(table); if (tpl && !tpl.applyRenderTpl) { this.setupFramingTpl(tpl); } return tpl; }, initRenderTpl: function() { var tpl = this.getTpl('renderTpl'); if (tpl && !tpl.renderContent) { this.setupRenderTpl(tpl); } return tpl; }, setupFramingTpl: function(frameTpl) { frameTpl.applyRenderTpl = this.doApplyRenderTpl; frameTpl.renderDockedItems = this.doRenderFramingDockedItems; }, setupRenderTpl: function(renderTpl) { renderTpl.renderBody = renderTpl.renderContent = this.doRenderContent; renderTpl.renderPadding = this.doRenderPadding; }, updateFrame: function() { if (Ext.supports.CSS3BorderRadius || !this.frame) { return; } var me = this, dom = me.el.dom, frameTable = me.frameTable, oldFrameBody = me.frameBody, oldFrameBodyDom = oldFrameBody.dom, frameInfo = me.getFrameInfo(), childEls, childElName, div, el, first, frameData, frameDom, frameTpl, i, newBody, newFrameEls; div = document.createElement('div'); frameData = me.getFrameRenderData(); frameTpl = me.getFrameTpl(frameInfo.table); frameTpl.insertFirst(div, frameData); newFrameEls = div.querySelectorAll('[data-ref]'); newBody = div.querySelector('[data-ref="frameBody"]'); for (first = oldFrameBodyDom; first.parentNode !== dom; ) { first = first.parentNode; } while (div.firstChild) { dom.insertBefore(div.firstChild, first); } newBody.parentNode.replaceChild(oldFrameBodyDom, newBody); oldFrameBodyDom.className = newBody.className; oldFrameBody.setSize(); childEls = me.getChildEls(); if (frameTable) { frameTable.destroy(); me.frameTable = null; } for (childElName in childEls) { if (childEls[childElName].frame) { el = me[childElName]; if (el && el !== oldFrameBody) { el.destroy(); me[childElName] = null; } } } for (i = newFrameEls.length; i--; ) { childElName = (frameDom = newFrameEls[i]).getAttribute('data-ref'); if (childElName !== 'frameBody') { me[childElName] = new Ext.dom.Element(frameDom); } } }, frameInfoCache: {} } }); Ext.define('Ext.state.Provider', { mixins: { observable: 'Ext.util.Observable' }, prefix: 'ext-', constructor: function(config) { var me = this; Ext.apply(me, config); me.state = {}; me.mixins.observable.constructor.call(me); }, get: function(name, defaultValue) { var ret = this.state[name]; return ret === undefined ? defaultValue : ret; }, 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, keyValue, values, vLen, v; 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) { values = value.split('^'); vLen = values.length; for (v = 0; v < vLen; v++) { value = values[v]; all.push(me.decodeValue(value)); } }; return all; case 'o': all = {}; if (value) { values = value.split('^'); vLen = values.length; for (v = 0; v < vLen; v++) { value = values[v]; keyValue = value.split('='); all[keyValue[0]] = me.decodeValue(keyValue[1]); } }; 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.toUTCString(); } 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.state.Manager', { singleton: true, requires: [ 'Ext.state.Provider' ], constructor: function() { this.provider = new Ext.state.Provider(); }, setProvider: function(stateProvider) { this.provider = stateProvider; }, get: function(key, defaultValue) { return this.provider.get(key, defaultValue); }, set: function(key, value) { this.provider.set(key, value); }, clear: function(key) { this.provider.clear(key); }, getProvider: function() { return this.provider; } }); Ext.define('Ext.state.Stateful', { mixinId: 'state', requires: [ 'Ext.state.Manager' ], stateful: false, saveDelay: 100, constructor: function() { var me = this; if (!me.stateEvents) { me.stateEvents = []; } if (me.stateful !== false) { me.addStateEvents(me.stateEvents); me.initState(); } }, addStateEvents: function(events) { var me = this, i, event, stateEventsByName, eventArray; if (me.stateful && me.getStateId()) { eventArray = (typeof events === 'string') ? arguments : events; stateEventsByName = me.stateEventsByName || (me.stateEventsByName = {}); for (i = eventArray.length; i--; ) { event = eventArray[i]; if (event && !stateEventsByName[event]) { stateEventsByName[event] = 1; me.on(event, me.onStateChange, me); } } } }, onStateChange: function() { var me = this, delay = me.saveDelay, statics, runner; if (!me.stateful) { return; } if (delay) { if (!me.stateTask) { statics = Ext.state.Stateful; runner = statics.runner || (statics.runner = new Ext.util.TaskRunner()); me.stateTask = runner.newTask({ run: me.saveState, scope: me, interval: delay, repeat: 1, fireIdleEvent: false }); } me.stateTask.start(); } else { me.saveState(); } }, saveState: function() { var me = this, id = me.stateful && me.getStateId(), hasListeners = me.hasListeners, plugins, plugin, i, len, state, pluginState; if (id) { state = me.getState() || {}; plugins = me.getPlugins() || []; for (i = 0 , len = plugins.length; i < len; i++) { plugin = plugins[i]; if (plugin && plugin.getState) { pluginState = plugin.getState(state); if (pluginState && !state[plugin.ptype]) { state[plugin.ptype] = pluginState; } } } if (!hasListeners.beforestatesave || me.fireEvent('beforestatesave', me, state) !== false) { Ext.state.Manager.set(id, state); if (hasListeners.statesave) { me.fireEvent('statesave', me, state); } } } }, getState: function() { return null; }, applyState: function(state) { if (state) { Ext.apply(this, state); } }, getStateId: function() { var me = this; return me.stateId || (me.autoGenId ? null : me.id); }, initState: function() { var me = this, id = me.stateful && me.getStateId(), hasListeners = me.hasListeners, state, combinedState, i, len, plugins, plugin, pluginType; if (id) { combinedState = Ext.state.Manager.get(id); if (combinedState) { state = Ext.apply({}, combinedState); if (!hasListeners.beforestaterestore || me.fireEvent('beforestaterestore', me, combinedState) !== false) { plugins = me.getPlugins() || []; for (i = 0 , len = plugins.length; i < len; i++) { plugin = plugins[i]; if (plugin) { pluginType = plugin.ptype; if (plugin.applyState) { plugin.applyState(state[pluginType], combinedState); } delete state[pluginType]; } } me.applyState(state); if (hasListeners.staterestore) { me.fireEvent('staterestore', me, combinedState); } } } } }, savePropToState: function(propName, state, stateName) { var me = this, value = me[propName], config = me.initialConfig; if (me.hasOwnProperty(propName)) { if (!config || config[propName] !== value) { if (state) { state[stateName || propName] = value; } return true; } } return false; }, savePropsToState: function(propNames, state) { var me = this, i, n; if (typeof propNames === 'string') { me.savePropToState(propNames, state); } else { for (i = 0 , n = propNames.length; i < n; ++i) { me.savePropToState(propNames[i], state); } } return state; }, destroy: function() { var me = this, task = me.stateTask; if (task) { task.destroy(); me.stateTask = null; } me.clearListeners(); } }); Ext.define('Ext.util.Focusable', { mixinId: 'focusable', hasFocus: false, focusable: false, focusCls: 'focus', initFocusable: Ext.emptyFn, initFocusableEvents: function() { this.initFocusableElement(); }, getFocusClsEl: function() { return this.getFocusEl(); }, getFocusEl: function() { return this.element || this.el; }, destroyFocusable: function() { this.focusListeners = Ext.destroy(this.focusListeners); delete this.focusTask; }, enableFocusable: Ext.emptyFn, disableFocusable: function() { var me = this, focusTarget, focusCls = me.focusCls, focusClsEl; if (me.hasFocus) { focusTarget = me.findFocusTarget(); if (focusTarget) { focusTarget.focus(); } } focusClsEl = me.getFocusClsEl(); if (focusCls && focusClsEl) { focusClsEl.removeCls(me.removeClsWithUI(focusCls, true)); } }, isFocusable: function(deep) { var me = this, focusEl; if (!me.focusable && (!me.isContainer || !deep)) { return false; } focusEl = me.getFocusEl(); if (focusEl && me.canFocus()) { return focusEl.isFocusable(deep); } return false; }, canFocus: function() { var me = this; return (me.isContainer || me.focusable) && me.rendered && !me.destroying && !me.isDestroyed && !me.disabled && me.isVisible(true); }, focus: function(selectText, delay, callback, scope) { var me = this, focusTarget, focusElDom, containerScrollTop; if ((!me.focusable && !me.isContainer) || me.isDestroyed || me.destroying) { return; } if (delay) { me.getFocusTask().delay(Ext.isNumber(delay) ? delay : 10, me.focus, me, [ selectText, false, callback, scope ]); return me; } me.cancelFocus(); if (me.canFocus()) { if (focusTarget = me.getFocusEl()) { if (focusTarget.isComponent) { return focusTarget.focus(selectText, delay, callback, scope); } focusElDom = focusTarget.dom; if (focusElDom) { if (focusTarget.needsTabIndex()) { focusElDom.tabIndex = -1; } if (me.floating) { containerScrollTop = me.container.dom.scrollTop; } focusTarget.focus(); if (selectText) { if (Ext.isArray(selectText)) { if (me.selectText) { me.selectText.apply(me, selectText); } } else if (focusElDom.select) { focusElDom.select(); } else if (me.selectText) { me.selectText(); } } Ext.callback(callback, scope); } if (me.floating) { if (me !== me.zIndexManager.getActive()) { me.toFront(true); } if (containerScrollTop !== undefined) { me.container.dom.scrollTop = containerScrollTop; } } } } else { focusTarget = me.findFocusTarget(); if (focusTarget) { return focusTarget.focus(selectText, delay, callback, scope); } } return me; }, cancelFocus: function() { var task = this.getFocusTask(); if (task) { task.cancel(); } }, beforeBlur: Ext.emptyFn, onBlur: function(e) { var me = this, container = me.focusableContainer, focusCls = me.focusCls, focusClsEl; if (!me.focusable || me.destroying) { return; } me.beforeBlur(e); if (container) { container.beforeFocusableChildBlur(me, e); } focusClsEl = me.getFocusClsEl(); if (focusCls && focusClsEl) { focusClsEl.removeCls(me.removeClsWithUI(focusCls, true)); } if (me.validateOnBlur) { me.validate(); } me.hasFocus = false; me.fireEvent('blur', me, e); me.postBlur(e); if (container) { container.afterFocusableChildBlur(me, e); } }, postBlur: Ext.emptyFn, beforeFocus: Ext.emptyFn, onFocus: function(e) { var me = this, container = me.focusableContainer, focusCls = me.focusCls, focusClsEl; if (!me.focusable) { return; } if (me.canFocus()) { me.beforeFocus(e); if (container) { container.beforeFocusableChildFocus(me, e); } focusClsEl = me.getFocusClsEl(); if (focusCls && focusClsEl) { focusClsEl.addCls(me.addClsWithUI(focusCls, true)); } if (!me.hasFocus) { me.hasFocus = true; me.fireEvent('focus', me, e); } me.postFocus(e); if (container) { container.afterFocusableChildFocus(me, e); } } }, postFocus: Ext.emptyFn, getTabIndex: function() { var me = this, el, index; if (!me.focusable) { return; } el = me.getFocusEl(); if (el) { if (el.isComponent) { index = el.getTabIndex(); } else if (el.isElement) { index = el.getAttribute(Ext.Element.tabIndexAttributeName); } else { return; } me.tabIndex = index; } else { index = me.tabIndex; } return index - 0; }, setTabIndex: function(newTabIndex) { var me = this, el; if (!me.focusable) { return; } me.tabIndex = newTabIndex; el = me.getFocusEl(); if (el) { if (el.isComponent) { el.setTabIndex(newTabIndex); } else if (el.isElement) { el.set({ tabindex: newTabIndex }); } } }, onFocusEnter: function(e) { var me = this; me.previousFocus = e.fromComponent || e.relatedTarget; me.containsFocus = true; me.fireEvent('focusenter', me, e); }, onFocusLeave: function(e) { var me = this; me.previousFocus = null; me.containsFocus = false; me.fireEvent('focusleave', me, e); }, privates: { revertFocus: function() { var me = this, focusTarget = me.previousFocus; me.previousFocus = null; if (focusTarget && me.containsFocus) { if (focusTarget.isComponent) { focusTarget.focus(); } else { focusTarget = Ext.fly(focusTarget); if (Ext.isIE8 || (focusTarget.isFocusable && focusTarget.isFocusable())) { focusTarget.focus(); } } } }, findFocusTarget: function() { var me = this, owner, focusTargets; for (owner = me.up(':not([disabled])'); owner; owner = owner.up(':not([disabled])')) { focusTargets = Ext.ComponentQuery.query(':focusable:not([hasFocus])', owner); if (focusTargets.length) { return focusTargets[0]; } if (owner.isFocusable && owner.isFocusable()) { return owner; } } }, initFocusableElement: function() { var me = this, tabIndex = me.tabIndex, focusEl = me.getFocusEl(), needsTabIndex; if (focusEl && !focusEl.isComponent) { needsTabIndex = focusEl.needsTabIndex(); if (needsTabIndex || tabIndex != null) { focusEl.dom.setAttribute('tabindex', tabIndex); } focusEl.dom.setAttribute(Ext.Component.componentIdAttribute, me.id); } }, getFocusTask: function() { if (!this.focusTask) { this.focusTask = Ext.focusTask; } return this.focusTask; }, blur: function() { var me = this, focusEl; if (!me.focusable || !me.rendered) { return; } focusEl = me.getFocusEl(); if (focusEl) { me.blurring = true; focusEl.blur(); delete me.blurring; } return me; }, disableTabbing: function() { var me = this, el = me.el, focusEl; if (!me.focusable) { return; } focusEl = me.getFocusEl(); if (el) { el.saveChildrenTabbableState(); } if (focusEl) { focusEl = focusEl.isComponent ? focusEl.getFocusEl() : focusEl; focusEl.saveTabbableState(); } }, enableTabbing: function() { var me = this, el = me.el, focusEl; if (!me.focusable) { return; } focusEl = me.getFocusEl(); if (focusEl) { focusEl = focusEl.isComponent ? focusEl.getFocusEl() : focusEl; focusEl.restoreTabbableState(); } if (el) { el.restoreChildrenTabbableState(); } } } }, function() { if (!Ext.focusTask) { Ext.focusTask = new Ext.util.DelayedTask(); } }); Ext.define('Ext.Component', { alternateClassName: 'Ext.AbstractComponent', xtype: [ 'component', 'box' ], requires: [ 'Ext.ComponentQuery', 'Ext.ComponentManager', 'Ext.util.ProtoElement', 'Ext.dom.CompositeElement', 'Ext.scroll.Scroller', 'Ext.scroll.TouchScroller', 'Ext.scroll.DomScroller' ], mixins: [ 'Ext.mixin.Inheritable', 'Ext.util.Floating', 'Ext.util.Positionable', 'Ext.util.Observable', 'Ext.mixin.Bindable', 'Ext.util.Animate', 'Ext.util.ElementContainer', 'Ext.util.Renderable', 'Ext.state.Stateful', 'Ext.util.Focusable' ], uses: [ 'Ext.overrides.*', 'Ext.Element', 'Ext.DomHelper', 'Ext.XTemplate', 'Ext.ComponentLoader', 'Ext.layout.Context', 'Ext.layout.Layout', 'Ext.layout.component.Auto', 'Ext.LoadMask', 'Ext.ZIndexManager', 'Ext.util.DelayedTask', 'Ext.resizer.Resizer', 'Ext.util.ComponentDragger' ], statics: { AUTO_ID: 1000, pendingLayouts: null, layoutSuspendCount: 0, DIRECTION_TOP: 'top', DIRECTION_RIGHT: 'right', DIRECTION_BOTTOM: 'bottom', DIRECTION_LEFT: 'left', VERTICAL_DIRECTION_Re: /^(?:top|bottom)$/, INVALID_ID_CHARS_Re: /[\.,\s]/g, componentIdAttribute: 'componentId', cancelLayout: function(comp, isDestroying) { var context = this.runningLayoutContext || this.pendingLayouts; if (context) { context.cancelComponent(comp, false, isDestroying); } }, fromElement: function(node, topmost) { var cmpIdAttr = Ext.Component.componentIdAttribute, target = Ext.getDom(node), cache = Ext.ComponentManager.all, cmpId, cmp; if (topmost) { topmost = Ext.getDom(topmost); } else { topmost = document.body.parentNode; } while (target && target.nodeType === 1 && target !== topmost) { cmpId = target.getAttribute(cmpIdAttr) || target.id; if (cmpId) { cmp = cache[cmpId]; if (cmp) { return cmp; } } target = target.parentNode; } return null; }, flushLayouts: function() { var me = this, context = me.pendingLayouts; if (context && context.invalidQueue.length) { me.pendingLayouts = null; me.runningLayoutContext = context; Ext.override(context, { runComplete: function() { me.runningLayoutContext = null; var result = this.callParent(); if (Ext.GlobalEvents.hasListeners.afterlayout) { Ext.GlobalEvents.fireEvent('afterlayout'); } return result; } }); context.run(); } }, resumeLayouts: function(flush) { if (this.layoutSuspendCount && !--this.layoutSuspendCount) { if (flush) { this.flushLayouts(); } if (Ext.GlobalEvents.hasListeners.resumelayouts) { Ext.GlobalEvents.fireEvent('resumelayouts'); } } }, suspendLayouts: function() { ++this.layoutSuspendCount; }, updateLayout: function(comp, defer) { var me = this, running = me.runningLayoutContext, pending; if (running) { running.queueInvalidate(comp); } else { pending = me.pendingLayouts || (me.pendingLayouts = new Ext.layout.Context()); pending.queueInvalidate(comp); if (!defer && !me.layoutSuspendCount && !comp.isLayoutSuspended()) { me.flushLayouts(); } } } }, $configPrefixed: false, $configStrict: false, config: { data: null, maxHeight: null, maxWidth: null, minHeight: null, minWidth: null, scrollable: null }, defaultBindProperty: 'html', alignTarget: null, autoRender: false, autoShow: false, baseCls: Ext.baseCSSPrefix + 'component', childEls: { frameTable: { frame: true }, frameTL: { frame: 'tl' }, frameTC: { frame: 'tc' }, frameTR: { frame: 'tr' }, frameML: { frame: 'ml' }, frameBody: { frame: 'mc' }, frameMR: { frame: 'mr' }, frameBL: { frame: 'bl' }, frameBC: { frame: 'bc' }, frameBR: { frame: 'br' } }, componentLayout: 'autocomponent', defaultAlign: 'c-c', disabled: false, disabledRe: /^(?:button|input|select|textarea|optgroup|option|fieldset)$/i, nonMaskableRe: (function() { var re = [ 'input', 'select', 'textarea', 'optgroup', 'option', 'table' ]; if (Ext.isIE9m && !(Ext.isIE9 && !Ext.isIEQuirks)) { re.push('p'); } return new RegExp('^(?:' + re.join('|') + ')$', 'i'); }()), disabledCls: Ext.baseCSSPrefix + 'item-disabled', draggable: false, floating: false, hidden: false, hideMode: 'display', maskElement: null, renderTpl: [ '', '
', '', '{%this.renderContent(out,values)%}', '
' ], resizeHandles: 'all', shrinkWrap: 2, toFrontOnShow: true, synthetic: false, tplWriteMode: 'overwrite', ui: 'default', uiCls: [], weight: null, allowDomMove: true, autoGenId: false, borderBoxCls: Ext.baseCSSPrefix + 'border-box', componentLayoutCounter: 0, contentPaddingProperty: 'padding', deferLayouts: false, frameSize: null, horizontalPosProp: 'left', isComponent: true, _isLayoutRoot: false, layoutSuspendCount: 0, liquidLayout: false, maskOnDisable: true, offsetsCls: Ext.baseCSSPrefix + 'hidden-offsets', rendered: false, rootCls: Ext.baseCSSPrefix + 'body', scrollerCls: Ext.baseCSSPrefix + 'scroll-scroller', scrollerSelector: '.' + Ext.baseCSSPrefix + 'scroll-scroller', _scrollFlags: { auto: { auto: { overflowX: 'auto', overflowY: 'auto', x: true, y: true, both: true }, 'false': { overflowX: 'auto', overflowY: 'hidden', x: true, y: false, both: false }, scroll: { overflowX: 'auto', overflowY: 'scroll', x: true, y: true, both: true } }, 'false': { auto: { overflowX: 'hidden', overflowY: 'auto', x: false, y: true, both: false }, 'false': { overflowX: 'hidden', overflowY: 'hidden', x: false, y: false, both: false }, scroll: { overflowX: 'hidden', overflowY: 'scroll', x: false, y: true, both: false } }, scroll: { auto: { overflowX: 'scroll', overflowY: 'auto', x: true, y: true, both: true }, 'false': { overflowX: 'scroll', overflowY: 'hidden', x: true, y: false, both: false }, scroll: { overflowX: 'scroll', overflowY: 'scroll', x: true, y: true, both: true } }, none: { overflowX: '', overflowY: '', x: false, y: false, both: false } }, _scrollableCfg: { x: { x: true, y: false }, y: { x: false, y: true }, horizontal: { x: true, y: false }, vertical: { x: false, y: true }, both: { x: true, y: true }, 'true': { x: true, y: true } }, validIdRe: Ext.validIdRe, constructor: function(config) { var me = this, i, len, xhooks, controller, autoScroll, overflowX, overflowY, scrollable; config = config || {}; if (config.initialConfig) { if (config.isAction) { me.baseAction = config; } config = config.initialConfig; } else if (config.tagName || config.dom || Ext.isString(config)) { config = { applyTo: config, id: config.id || config }; } me.initialConfig = config; me.getId(); me.protoEl = new Ext.util.ProtoElement(); me.$calledInitConfig = true; me.initConfig(config); delete me.$calledInitConfig; if (me.scrollable == null) { autoScroll = me.autoScroll; if (autoScroll) { scrollable = !!autoScroll; } else { overflowX = me.overflowX; overflowY = me.overflowY; if (overflowX || overflowY) { scrollable = { x: (overflowX && overflowX !== 'hidden') ? overflowX : false, y: (overflowY && overflowY !== 'hidden') ? overflowY : false }; } } if (scrollable) { me.setScrollable(scrollable); } } xhooks = me.xhooks; if (xhooks) { delete me.xhooks; Ext.override(me, xhooks); } me.mixins.elementCt.constructor.call(me); if (!me.validIdRe.test(me.id)) { Ext.Error.raise('Invalid component "id": "' + me.id + '"'); } if (!me.validIdRe.test(me.itemId)) { Ext.Error.raise('Invalid component "itemId": "' + me.itemId + '"'); } me.setupProtoEl(); if (me.cls) { me.initialCls = me.cls; me.protoEl.addCls(me.cls); } if (me.style) { me.initialStyle = me.style; me.protoEl.setStyle(me.style); } me.renderData = me.renderData || {}; me.initComponent(); if (!me.preventRegister) { Ext.ComponentManager.register(me); } me.mixins.state.constructor.call(me); me.addStateEvents('resize'); controller = me.getController(); if (controller) { controller.init(me); } if (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.disabled) { me.disabled = false; me.disable(true); } if (me.renderTo) { me.render(me.renderTo); } if (me.autoShow && !me.initOwnerCt) { 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; } if (me.baseAction) { me.baseAction.addComponent(me); } }, beforeInitConfig: function() { if (!this.$calledInitConfig) { Ext.Error.raise('initConfig should not be called by subclasses, it will be called by Ext.Component'); } this.mixins.observable.constructor.call(this); }, addCls: function(cls) { var me = this, el = me.rendered ? me.el : me.protoEl; el.addCls.apply(el, arguments); return me; }, addClsWithUI: function(classes, skip) { var me = this, clsArray = [], i = 0, uiCls = me.uiCls = Ext.Array.clone(me.uiCls), activeUI = me.activeUI, length, cls; if (typeof classes === "string") { classes = (classes.indexOf(' ') < 0) ? [ classes ] : Ext.String.splitWords(classes); } length = classes.length; for (; i < length; i++) { cls = classes[i]; if (cls && !me.hasUICls(cls)) { uiCls.push(cls); if (activeUI) { clsArray = clsArray.concat(me.addUIClsToElement(cls)); } } } if (skip !== true && activeUI) { me.addCls(clsArray); } return clsArray; }, afterComponentLayout: function(width, height, oldWidth, oldHeight) { var me = this; if (++me.componentLayoutCounter === 1) { me.afterFirstLayout(width, height); } if (width !== oldWidth || height !== oldHeight) { me.onResize(width, height, oldWidth, oldHeight); } if (me.floating) { me.onAfterFloatLayout(); } }, addPlugin: function(plugin) { var me = this; plugin = me.constructPlugin(plugin); if (me.plugins) { me.plugins.push(plugin); } else { me.plugins = [ plugin ]; } if (me.pluginsInitialized) { me.initPlugin(plugin); } return plugin; }, addPropertyToState: function(state, propName, value) { var me = this, len = arguments.length; if (len === 3 || me.hasOwnProperty(propName)) { if (len < 3) { value = me[propName]; } if (value !== me.initialConfig[propName]) { (state || (state = {}))[propName] = value; } } return state; }, addUIClsToElement: function(uiCls) { var me = this, baseClsUI = me.baseCls + '-' + me.ui + '-' + uiCls, result = [ Ext.baseCSSPrefix + uiCls, me.baseCls + '-' + uiCls, baseClsUI ], childEls, childElName, el, suffix; if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { baseClsUI += '-'; childEls = me.getChildEls(); for (childElName in childEls) { suffix = childEls[childElName].frame; if (suffix && suffix !== true) { el = me[childElName]; if (el) { el.addCls(baseClsUI + suffix); } } } } return result; }, removeUIClsFromElement: function(uiCls) { var me = this, baseClsUI = me.baseCls + '-' + me.ui + '-' + uiCls, result = [ Ext.baseCSSPrefix + uiCls, me.baseCls + '-' + uiCls, baseClsUI ], childEls, childElName, el, suffix; if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { baseClsUI += '-'; childEls = me.getChildEls(); for (childElName in childEls) { suffix = childEls[childElName].frame; if (suffix && suffix !== true) { el = me[childElName]; if (el) { el.removeCls(baseClsUI + suffix); } } } } return result; }, adjustPosition: function(x, y) { var me = this, floatParentBox; if (me.isContainedFloater()) { floatParentBox = me.floatParent.getTargetEl().getViewRegion(); x += floatParentBox.left; y += floatParentBox.top; } return { x: x, y: y }; }, afterHide: function(cb, scope) { var me = this, container = me.focusableContainer; me.hiddenByLayout = null; if (this.ownerLayout) { this.updateLayout({ isRoot: false }); } Ext.callback(cb, scope || me); me.fireHierarchyEvent('hide'); me.fireEvent('hide', me); if (container) { container.onFocusableChildHide(me); } }, afterSetPosition: function(x, y) { var me = this; me.onPosition(x, y); if (me.hasListeners.move) { me.fireEvent('move', me, x, y); } }, afterShow: function(animateTarget, cb, scope) { var me = this, myEl = me.el, fromBox, toBox, ghostPanel; animateTarget = me.getAnimateTarget(animateTarget); if (!me.ghost) { animateTarget = null; } if (animateTarget) { toBox = { x: myEl.getX(), y: myEl.getY(), width: myEl.dom.offsetWidth, height: myEl.dom.offsetHeight }; fromBox = { x: animateTarget.getX(), y: animateTarget.getY(), width: animateTarget.dom.offsetWidth, height: animateTarget.dom.offsetHeight }; myEl.addCls(me.offsetsCls); ghostPanel = me.ghost(); ghostPanel.el.stopAnimation(); ghostPanel.setX(-10000); me.ghostBox = toBox; ghostPanel.el.animate({ from: fromBox, to: toBox, listeners: { afteranimate: function() { delete ghostPanel.componentLayout.lastComponentSize; me.unghost(); delete me.ghostBox; myEl.removeCls(me.offsetsCls); me.onShowComplete(cb, scope); } } }); } else { me.onShowComplete(cb, scope); } me.fireHierarchyEvent('show'); }, animate: function(animObj) { var me = this, hasToWidth, hasToHeight, toHeight, toWidth, to, clearWidth, clearHeight, curWidth, w, curHeight, h, isExpanding, wasConstrained, wasConstrainedHeader, passedCallback, oldOverflow; animObj = animObj || {}; to = animObj.to || {}; if (Ext.fx.Manager.hasFxBlock(me.id)) { return me; } hasToWidth = Ext.isDefined(to.width); if (hasToWidth) { toWidth = Ext.Number.constrain(to.width, me.minWidth, me.maxWidth); } hasToHeight = Ext.isDefined(to.height); if (hasToHeight) { toHeight = Ext.Number.constrain(to.height, me.minHeight, me.maxHeight); } if (!animObj.dynamic && (hasToWidth || hasToHeight)) { curWidth = (animObj.from ? animObj.from.width : undefined) || me.getWidth(); w = curWidth; curHeight = (animObj.from ? animObj.from.height : undefined) || me.getHeight(); h = curHeight; isExpanding = false; if (hasToHeight && toHeight > curHeight) { h = toHeight; isExpanding = true; } if (hasToWidth && toWidth > curWidth) { w = toWidth; isExpanding = true; } if (hasToHeight || hasToWidth) { oldOverflow = me.el.getStyle('overflow'); if (oldOverflow !== 'hidden') { me.el.setStyle('overflow', 'hidden'); } } if (isExpanding) { clearWidth = !Ext.isNumber(me.width); clearHeight = !Ext.isNumber(me.height); me.setSize(w, h); me.el.setSize(curWidth, curHeight); if (clearWidth) { delete me.width; } if (clearHeight) { delete me.height; } } if (hasToWidth) { to.width = toWidth; } if (hasToHeight) { to.height = toHeight; } } wasConstrained = me.constrain; wasConstrainedHeader = me.constrainHeader; if (wasConstrained || wasConstrainedHeader) { me.constrain = me.constrainHeader = false; passedCallback = animObj.callback; animObj.callback = function() { me.constrain = wasConstrained; me.constrainHeader = wasConstrainedHeader; if (passedCallback) { passedCallback.call(animObj.scope || me, arguments); } if (oldOverflow !== 'hidden') { me.el.setStyle('overflow', oldOverflow); } }; } return me.mixins.animate.animate.apply(me, arguments); }, applyScrollable: function(scrollable, oldScrollable) { var me = this, rendered = me.rendered, scrollableCfg, innerEl; if (scrollable) { if (scrollable === true || typeof scrollable === 'string') { scrollableCfg = me._scrollableCfg[scrollable]; if (!scrollableCfg) { Ext.Error.raise("'" + scrollable + "' is not a valid value for 'scrollable'"); } scrollable = scrollableCfg; } if (oldScrollable) { oldScrollable.setConfig(scrollable); scrollable = oldScrollable; } else { scrollable = Ext.Object.chain(scrollable); if (rendered) { scrollable.element = me.getOverflowEl(); innerEl = me.getScrollerEl(); if (innerEl) { scrollable.innerElement = innerEl; } } scrollable.autoRefresh = false; if (Ext.supports.touchScroll === 1) { scrollable.translatable = { translationMethod: 'scrollparent' }; scrollable.indicators = false; } scrollable = Ext.scroll.Scroller.create(scrollable); scrollable.component = me; } } else if (oldScrollable) { oldScrollable.setConfig({ x: false, y: false }); oldScrollable.destroy(); } if (me.rendered) { me.getOverflowStyle(); me.updateLayout(); } return scrollable; }, beforeComponentLayout: function() { return true; }, beforeDestroy: Ext.emptyFn, beforeLayout: function() { if (this.floating) { this.onBeforeFloatLayout(); } }, beforeSetPosition: function(x, y, animate) { var me = this, pos = null, x0, hasX, hasY, adj; if (x) { if (Ext.isNumber(x0 = x[0])) { animate = y; y = x[1]; x = x0; } else if ((x0 = x.x) !== undefined) { animate = y; y = x.y; x = x0; } } if (me.constrain || me.constrainHeader) { pos = me.calculateConstrainedPosition(null, [ x, y ], true); if (pos) { x = pos[0]; y = pos[1]; } } hasX = (x !== undefined); hasY = (y !== undefined); if (hasX || hasY) { me.x = x; me.y = y; adj = me.adjustPosition(x, y); pos = { x: adj.x, y: adj.y, anim: animate, hasX: hasX, hasY: hasY }; } return pos; }, beforeShow: Ext.emptyFn, bubble: function(fn, scope, args) { var p = this; while (p) { if (fn.apply(scope || p, args || [ p ]) === false) { break; } p = p.getBubbleTarget(); } return this; }, cloneConfig: function(overrides) { overrides = overrides || {}; var id = overrides.id || Ext.id(), cfg = Ext.applyIf(overrides, this.initialConfig), self; cfg.id = id; self = Ext.getClass(this); return new self(cfg); }, destroy: function() { var me = this, selectors = me.renderSelectors, viewModel = me.getConfig('viewModel', true), session = me.getConfig('session', true), selector, ownerCt, el; if (!me.isDestroyed) { if (!me.hasListeners.beforedestroy || me.fireEvent('beforedestroy', me) !== false) { me.destroying = true; ownerCt = me.floatParent || me.ownerCt; if (me.floating) { delete me.floatParent; if (me.zIndexManager) { me.zIndexManager.unregister(me); me.zIndexManager = null; } } me.removeBindings(); me.beforeDestroy(); if (viewModel && viewModel.isViewModel) { viewModel.destroy(); me.viewModel = null; } if (session && session.isSession) { if (session.getAutoDestroy()) { session.destroy(); } me.session = null; } if (ownerCt && ownerCt.remove) { ownerCt.remove(me, false); } me.stopAnimation(); me.onDestroy(); Ext.destroy(me.plugins); me.componentLayout = null; if (me.hasListeners.destroy) { me.fireEvent('destroy', me); } if (!me.preventRegister) { Ext.ComponentManager.unregister(me); } me.mixins.state.destroy.call(me); if (me.floating) { me.onFloatDestroy(); } me.clearListeners(); if (me.rendered) { if (!me.preserveElOnDestroy) { me.el.destroy(); } me.el.component = null; me.mixins.elementCt.destroy.call(me); if (selectors) { for (selector in selectors) { if (selectors.hasOwnProperty(selector)) { el = me[selector]; if (el) { delete me[selector]; el.destroy(); } } } } me.data = me.el = me.frameBody = me.rendered = null; } me.destroying = false; me.isDestroyed = true; } } }, disable: function(silent, fromParent) { var me = this, container = me.focusableContainer, inherited = me.getInherited(); if (!fromParent) { inherited.disabled = true; } if (me.maskOnDisable) { inherited.disableMask = true; } if (!me.disabled) { me.addCls(me.disabledCls); if (me.rendered) { me.onDisable(); } else { me.disableOnRender = true; } me.disabled = true; if (silent !== true) { me.fireEvent('disable', me); } if (container) { container.onFocusableChildDisable(me); } } return me; }, enable: function(silent, fromParent) { var me = this, container = me.focusableContainer, inherited = me.getInherited(); if (!fromParent) { delete me.getInherited().disabled; } if (me.maskOnDisable) { delete inherited.disableMask; } if (me.disabled) { if (!(fromParent && inherited.hasOwnProperty('disabled'))) { me.disableOnRender = false; me.removeCls(me.disabledCls); if (me.rendered) { me.onEnable(); } me.disabled = false; if (silent !== true) { me.fireEvent('enable', me); } if (container) { container.onFocusableChildEnable(me); } } } return me; }, findParentBy: function(fn) { var p; for (p = this.getRefOwner(); p && !fn(p, this); p = p.getRefOwner()) {} return p || null; }, findParentByType: function(xtype) { return Ext.isFunction(xtype) ? this.findParentBy(function(p) { return p.constructor === xtype; }) : this.up(xtype); }, findPlugin: function(ptype) { var i, plugins = this.plugins, ln = plugins && plugins.length; for (i = 0; i < ln; i++) { if (plugins[i].ptype === ptype) { return plugins[i]; } } }, getAnimateTarget: function(target) { target = target || this.animateTarget; if (target) { target = target.isComponent ? target.getEl() : Ext.get(target); } return target || null; }, getBubbleTarget: function() { return this.getRefOwner(); }, getComponentLayout: function() { var me = this; if (!me.componentLayout || !me.componentLayout.isLayout) { me.setComponentLayout(Ext.layout.Layout.create(me.componentLayout, 'autocomponent')); } return me.componentLayout; }, getEl: function() { return this.el; }, getHeight: function() { return this.el.getHeight(); }, initInheritedState: function(inheritedState) { var me = this, layout = me.componentLayout; if (me.hidden) { inheritedState.hidden = true; } if (me.collapseImmune) { inheritedState.collapseImmune = true; } if (me.modelValidation !== undefined) { inheritedState.modelValidation = me.modelValidation; } me.mixins.bindable.initInheritedState.call(me, inheritedState); if (layout && layout.initInheritedState) { layout.initInheritedState(inheritedState); } }, getId: function() { var me = this, xtype; if (!(me.id || (me.id = me.initialConfig.id))) { xtype = me.getXType(); if (xtype) { xtype = xtype.replace(Ext.Component.INVALID_ID_CHARS_Re, '-'); } else { xtype = Ext.name.toLowerCase() + '-comp'; } me.id = xtype + '-' + me.getAutoId(); } return me.id; }, getItemId: function() { return this.itemId || this.id; }, getLoader: function() { var me = this, loader = me.loader; if (loader) { if (!loader.isLoader) { me.loader = new Ext.ComponentLoader(Ext.apply({ target: me }, loader)); } else { loader.setTarget(me); } return me.loader; } return null; }, getMaskTarget: function() { return this.maskElement ? this[this.maskElement] : null; }, getPlugin: function(pluginId) { var i, plugins = this.plugins, ln = plugins && plugins.length; for (i = 0; i < ln; i++) { if (plugins[i].pluginId === pluginId) { return plugins[i]; } } return null; }, getPosition: function(local) { var me = this, xy, isContainedFloater = me.isContainedFloater(), floatParentBox; if ((local === true) && !isContainedFloater) { return [ me.getLocalX(), me.getLocalY() ]; } xy = me.getXY(); if ((local === true) && isContainedFloater) { floatParentBox = me.floatParent.getTargetEl().getViewRegion(); xy[0] -= floatParentBox.left; xy[1] -= floatParentBox.top; } return xy; }, getScrollX: function() { var scroller = this.getScrollable(); return scroller ? scroller.getPosition().x : 0; }, getScrollY: function() { var scroller = this.getScrollable(); return scroller ? scroller.getPosition().y : 0; }, getSize: function(contentSize) { return this.el.getSize(contentSize); }, getSizeModel: function(ownerCtSizeModel) { var me = this, models = Ext.layout.SizeModel, ownerContext = me.componentLayout.ownerContext, width = me.width, height = me.height, typeofWidth, typeofHeight, hasPixelWidth, hasPixelHeight, heightModel, ownerLayout, policy, shrinkWrap, topLevel, widthModel, isFloating = me.floating || me.floated; if (ownerContext) { widthModel = ownerContext.widthModel; heightModel = ownerContext.heightModel; } if (!widthModel || !heightModel) { hasPixelWidth = ((typeofWidth = typeof width) === 'number'); hasPixelHeight = ((typeofHeight = typeof height) === 'number'); topLevel = isFloating || !(ownerLayout = me.ownerLayout); if (topLevel) { policy = Ext.layout.Layout.prototype.autoSizePolicy; shrinkWrap = isFloating ? 3 : me.shrinkWrap; if (hasPixelWidth) { widthModel = models.configured; } if (hasPixelHeight) { heightModel = models.configured; } } else { policy = ownerLayout.getItemSizePolicy(me, ownerCtSizeModel); shrinkWrap = ownerLayout.isItemShrinkWrap(me); } if (ownerContext) { ownerContext.ownerSizePolicy = policy; } shrinkWrap = (shrinkWrap === true) ? 3 : (shrinkWrap || 0); if (topLevel && shrinkWrap) { if (width && typeofWidth === 'string') { shrinkWrap &= 2; } if (height && typeofHeight === 'string') { shrinkWrap &= 1; } } if (shrinkWrap !== 3) { if (!ownerCtSizeModel) { ownerCtSizeModel = me.ownerCt && me.ownerCt.getSizeModel(); } if (ownerCtSizeModel) { shrinkWrap |= (ownerCtSizeModel.width.shrinkWrap ? 1 : 0) | (ownerCtSizeModel.height.shrinkWrap ? 2 : 0); } } if (!widthModel) { if (!policy.setsWidth) { if (hasPixelWidth) { widthModel = models.configured; } else { widthModel = (shrinkWrap & 1) ? models.shrinkWrap : models.natural; } } else if (policy.readsWidth) { if (hasPixelWidth) { widthModel = models.calculatedFromConfigured; } else { widthModel = (shrinkWrap & 1) ? models.calculatedFromShrinkWrap : models.calculatedFromNatural; } } else { widthModel = models.calculated; } } if (!heightModel) { if (!policy.setsHeight) { if (hasPixelHeight) { heightModel = models.configured; } else { heightModel = (shrinkWrap & 2) ? models.shrinkWrap : models.natural; } } else if (policy.readsHeight) { if (hasPixelHeight) { heightModel = models.calculatedFromConfigured; } else { heightModel = (shrinkWrap & 2) ? models.calculatedFromShrinkWrap : models.calculatedFromNatural; } } else { heightModel = models.calculated; } } } return widthModel.pairsByHeightOrdinal[heightModel.ordinal]; }, getState: function() { var me = this, state = null, sizeModel = me.getSizeModel(); if (sizeModel.width.configured) { state = me.addPropertyToState(state, 'width'); } if (sizeModel.height.configured) { state = me.addPropertyToState(state, 'height'); } return state; }, getWidth: function() { return this.el.getWidth(); }, getXType: function() { return this.self.xtype; }, getXTypes: function() { var self = this.self, xtypes, parentPrototype, parentXtypes; if (!self.xtypes) { xtypes = []; parentPrototype = this; while (parentPrototype) { parentXtypes = parentPrototype.xtypes; if (parentXtypes !== undefined) { xtypes.unshift.apply(xtypes, parentXtypes); } parentPrototype = parentPrototype.superclass; } self.xtypeChain = xtypes; self.xtypes = xtypes.join('/'); } return self.xtypes; }, hasCls: function(cls) { var el = this.rendered ? this.el : this.protoEl; return el.hasCls.apply(el, arguments); }, hasUICls: function(cls) { var me = this, uiCls = me.uiCls || []; return Ext.Array.contains(uiCls, cls); }, hide: function(animateTarget, cb, scope) { var me = this; if (me.pendingShow) { me.pendingShow = false; } if (!(me.rendered && !me.isVisible())) { if (!me.hasListeners.beforehide || me.fireEvent('beforehide', me) !== false || me.hierarchicallyHidden) { me.getInherited().hidden = me.hidden = true; if (me.rendered) { me.onHide.apply(me, arguments); } } } return me; }, initComponent: function() { var me = this, width = me.width, height = me.height; if (me.plugins && !me.plugins.processed) { me.plugins = me.constructPlugins(); } me.pluginsInitialized = true; if (width != null || height != null) { me.setSize(width, height); } if (me.listeners) { me.on(me.listeners); me.listeners = null; } if (me.focusable) { me.initFocusable(); } }, initEvents: function() { var me = this, afterRenderEvents = me.afterRenderEvents, afterRenderEvent, el, property, index, len; if (afterRenderEvents) { for (property in afterRenderEvents) { el = me[property]; if (el && el.on) { afterRenderEvent = afterRenderEvents[property]; for (index = 0 , len = afterRenderEvent.length; index < len; ++index) { me.mon(el, afterRenderEvent[index]); } } } } if (me.focusable) { me.initFocusableEvents(); } }, is: function(selector) { return Ext.ComponentQuery.is(this, selector); }, isDescendantOf: function(ancestor) { var p; for (p = this.getRefOwner(); p && p !== ancestor; p = p.getRefOwner()) {} return p || null; }, isAncestor: function(possibleDescendant) { while (possibleDescendant) { if (possibleDescendant.getRefOwner() === this) { return true; } possibleDescendant = possibleDescendant.getRefOwner(); } }, isDisabled: function() { return this.disabled; }, isDraggable: function() { return !!this.draggable; }, isDroppable: function() { return !!this.droppable; }, isFloating: function() { return this.floating; }, isHidden: function() { return this.hidden; }, isHierarchicallyHidden: function() { var child = this, hidden = false, parent, parentInheritedState; for (; (parent = child.ownerCt || child.floatParent); child = parent) { parentInheritedState = parent.getInherited(); if (parentInheritedState.hidden) { hidden = true; break; } if (child.getInherited().collapseImmune) { if (parent.collapsed && !child.collapseImmune) { hidden = true; break; } } else { hidden = !!parentInheritedState.collapsed; break; } } return hidden; }, isLayoutChild: function(ownerCandidate) { return !this.floating && !!this.up(ownerCandidate); }, isLayoutRoot: function() { var me = this, ownerLayout = me.ownerLayout; if (!ownerLayout || me._isLayoutRoot || me.floating) { return true; } return ownerLayout.isItemLayoutRoot(me); }, isLayoutSuspended: function() { var comp = this, ownerLayout; while (comp) { if (comp.layoutSuspendCount || comp.suspendLayout) { return true; } ownerLayout = comp.ownerLayout; if (!ownerLayout) { break; } comp = ownerLayout.owner; } return false; }, isVisible: function(deep) { var me = this, hidden; if (me.hidden || !me.rendered || me.isDestroyed) { hidden = true; } else if (deep) { hidden = me.isHierarchicallyHidden(); } return !hidden; }, isXType: function(xtype, shallow) { return shallow ? (Ext.Array.indexOf(this.xtypes, xtype) !== -1) : !!this.xtypesMap[xtype]; }, isMasked: function(deep) { var me = this; return !!(me.masked || (me.loadMask && me.loadMask.isVisible()) || (deep && me.getInherited().masked)); }, setMasked: function(isMasked) { var me = this, container = me.focusableContainer; if (isMasked) { me.masked = true; me.getInherited().masked = isMasked; } else { me.masked = false; delete me.getInherited().masked; } if (container) { container.onFocusableChildMasked(me, isMasked); } return me; }, mask: function(msg, msgCls, elHeight) { var box = this.lastBox, target = this.getMaskTarget() || this.el; if (box) { elHeight = box.height; } target.mask(msg, msgCls, elHeight); this.setMasked(true); }, nextNode: function(selector, includeSelf) { var node = this, ownerCt = node.ownerCt, result, it, len, i, sib; if (includeSelf && node.is(selector)) { return node; } if (ownerCt) { for (it = ownerCt.items.items , i = Ext.Array.indexOf(it, node) + 1 , len = it.length; i < len; i++) { sib = it[i]; if (sib.is(selector)) { return sib; } if (sib.down) { result = sib.down(selector); if (result) { return result; } } } return ownerCt.nextNode(selector); } return null; }, 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; }, onAdded: function(container, pos, instanced) { var me = this, inheritedState = me.inheritedState; me.ownerCt = container; if (inheritedState && instanced) { me.invalidateInheritedState(); } if (me.reference) { me.fixReference(); } if (me.hasListeners && me.hasListeners.added) { me.fireEvent('added', me, container, pos); } if (Ext.GlobalEvents.hasListeners.added) { me.fireHierarchyEvent('added'); } }, onRemoved: function(destroying) { var me = this, refHolder; if (Ext.GlobalEvents.hasListeners.removed) { me.fireHierarchyEvent('removed'); } if (me.hasListeners.removed) { me.fireEvent('removed', me, me.ownerCt); } if (me.reference) { refHolder = me.lookupReferenceHolder(); if (refHolder) { refHolder.clearReference(me); } } if (!destroying) { me.removeBindings(); } if (me.inheritedState && !destroying) { me.invalidateInheritedState(); } me.ownerCt = me.ownerLayout = null; }, onBoxReady: function(width, height) { var me = this, scroller = me.scrollable; if (me.resizable) { me.initResizable(me.resizable); } if (me.draggable) { me.initDraggable(); } if (scroller) { if (me.touchScroll && scroller.isTouchScroller) { scroller.setInnerElement(me.getScrollerEl()); } scroller.setElement(me.getOverflowEl()); if (Ext.isIE) { Ext.on('show', me.onGlobalShow, me); } } if (me.hasListeners.boxready) { me.fireEvent('boxready', me, width, height); } }, onDestroy: function() { var me = this, controller = me.controller, container = me.focusableContainer; if (me.bind) { me.removeBindings(); } if (controller) { controller.destroy(); } me.controller = null; if (me.rendered) { Ext.destroy(me.dd, me.resizer, me.proxy, me.proxyWrap, me.resizerComponent, me.scrollable, me.contentEl); } if (container) { container.onFocusableChildDestroy(me); } if (me.focusable) { me.destroyFocusable(); } Ext.destroy(me.componentLayout, me.loadMask, me.floatingDescendants); }, onDisable: function() { var me = this, dom, nodeName; if (me.focusable) { me.disableFocusable(); } if (me.maskOnDisable && !me.getInheritedConfig('disableMask', true)) { dom = me.el.dom; nodeName = dom.nodeName; if (me.disabledRe.test(nodeName)) { dom.disabled = true; } if (!me.nonMaskableRe.test(nodeName)) { me.mask(); } } }, onEnable: function() { var me = this, dom, nodeName; if (me.focusable) { me.enableFocusable(); } if (me.maskOnDisable && me.getInherited().hasOwnProperty('masked')) { dom = me.el.dom; nodeName = dom.nodeName; if (me.disabledRe.test(nodeName)) { dom.disabled = false; } if (!me.nonMaskableRe.test(nodeName)) { me.unmask(); } } }, onGlobalShow: function(c) { if (this.up(c)) { this.getScrollable().restoreState(); } }, onHide: function(animateTarget, cb, scope) { var me = this, ghostPanel, fromSize, toBox; me.revertFocus(); animateTarget = me.getAnimateTarget(animateTarget); if (!me.ghost) { animateTarget = null; } if (animateTarget) { toBox = { x: animateTarget.getX(), y: animateTarget.getY(), width: animateTarget.dom.offsetWidth, height: animateTarget.dom.offsetHeight }; ghostPanel = me.ghost(); ghostPanel.el.stopAnimation(); fromSize = me.getSize(); ghostPanel.el.animate({ to: toBox, listeners: { afteranimate: function() { delete ghostPanel.componentLayout.lastComponentSize; ghostPanel.el.hide(); ghostPanel.setHiddenState(true); ghostPanel.el.setSize(fromSize); me.afterHide(cb, scope); } } }); } me.el.hide(); if (!animateTarget) { me.afterHide(cb, scope); } }, onPosition: Ext.emptyFn, onResize: function(width, height, oldWidth, oldHeight) { var me = this; if (me.floating && me.constrain) { me.doConstrain(); } if (oldWidth) { me.refreshScroll(); } if (me.hasListeners.resize) { me.fireEvent('resize', me, width, height, oldWidth, oldHeight); } }, onShow: function() { var me = this; me.el.show(); me.updateLayout({ isRoot: false }); if (me.floating) { if (me.maximized) { me.fitContainer(); } else if (me.constrain) { me.doConstrain(); } } }, onShowComplete: function(cb, scope) { var me = this, container = me.focusableContainer; if (me.floating) { me.onFloatShow(); } Ext.callback(cb, scope || me); me.fireEvent('show', me); if (container) { container.onFocusableChildShow(me); } delete me.hiddenByLayout; }, onShowVeto: Ext.emptyFn, previousNode: function(selector, includeSelf) { var node = this, ownerCt = node.ownerCt, result, it, i, sib; if (includeSelf && node.is(selector)) { return node; } if (ownerCt) { for (it = ownerCt.items.items , i = Ext.Array.indexOf(it, node) - 1; i > -1; i--) { sib = it[i]; if (sib.query) { result = sib.query(selector); result = result[result.length - 1]; if (result) { return result; } } if (sib.is(selector)) { return sib; } } return ownerCt.previousNode(selector, true); } 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; }, registerFloatingItem: function(cmp) { var me = this; if (!me.floatingDescendants) { me.floatingDescendants = new Ext.ZIndexManager(me); } me.floatingDescendants.register(cmp); }, removeCls: function(cls) { var me = this, el = me.rendered ? me.el : me.protoEl; el.removeCls.apply(el, arguments); return me; }, removeClsWithUI: function(classes, skip) { var me = this, clsArray = [], i = 0, extArray = Ext.Array, remove = extArray.remove, uiCls = me.uiCls = extArray.clone(me.uiCls), activeUI = me.activeUI, length, cls; if (typeof classes === "string") { classes = (classes.indexOf(' ') < 0) ? [ classes ] : Ext.String.splitWords(classes); } length = classes.length; for (i = 0; i < length; i++) { cls = classes[i]; if (cls && me.hasUICls(cls)) { remove(uiCls, cls); if (activeUI) { clsArray = clsArray.concat(me.removeUIClsFromElement(cls)); } } } if (skip !== true && activeUI) { me.removeCls(clsArray); } return clsArray; }, resumeLayouts: function(flushOptions) { var me = this; if (!me.rendered) { return; } if (!me.layoutSuspendCount) { Ext.log.warn('Mismatched call to resumeLayouts - layouts are currently not suspended.'); } if (me.layoutSuspendCount && !--me.layoutSuspendCount) { me.suspendLayout = false; if (flushOptions && !me.isLayoutSuspended()) { me.updateLayout(flushOptions); } } }, scrollBy: function(deltaX, deltaY, animate) { var scroller = this.getScrollable(); if (scroller) { scroller.scrollBy(deltaX, deltaY, animate); } }, scrollTo: function(x, y, animate) { var scroller = this.getScrollable(); if (scroller) { scroller.scrollTo(x, y, animate); } }, setAutoScroll: function(scroll) { this.setScrollable(!!scroll); return this; }, setBorder: function(border, targetEl) { var me = this, initial = !!targetEl; if (me.rendered || initial) { if (!initial) { targetEl = me.el; } if (!border) { border = 0; } else if (border === true) { border = '1px'; } else { border = this.unitizeBox(border); } targetEl.setStyle('border-width', border); if (!initial) { me.updateLayout(); } } me.border = border; }, setDock: function(dock) { var me = this, ownerCt = me.ownerCt; if (dock !== me.dock) { if (ownerCt && ownerCt.moveDocked) { ownerCt.moveDocked(me, dock); } else { me.dock = dock; } } return me; }, setDisabled: function(disabled) { return this[disabled ? 'disable' : 'enable'](); }, setFlex: function(flex) { this.flex = flex; }, setHeight: function(height) { return this.setSize(undefined, height); }, setLoading: function(load, targetEl) { var me = this, config = { target: me }; if (me.rendered) { if (load !== false) { if (Ext.isString(load)) { config.msg = load; } else { Ext.apply(config, load); } if (!me.loadMask || !me.loadMask.isLoadMask) { if (targetEl && config.useTargetEl == null) { config.useTargetEl = true; } me.loadMask = new Ext.LoadMask(config); } else { Ext.apply(me.loadMask, config); } if (me.loadMask.isVisible()) { me.loadMask.afterShow(); } else { me.loadMask.show(); } } else { if (me.loadMask && me.loadMask.isLoadMask) { me.loadMask.hide(); } } } return me.loadMask; }, setMargin: function(margin, preventLayout) { var me = this; if (me.rendered) { if (!margin && margin !== 0) { margin = ''; } else { if (margin === true) { margin = 5; } margin = this.unitizeBox(margin); } me.margin = margin; me.margin$ = null; me.getEl().setStyle('margin', margin); if (!preventLayout) { me.updateLayout(me._notAsLayoutRoot); } } else { me.margin = margin; } }, setOverflowXY: function(overflowX, overflowY) { this.setScrollable({ x: (overflowX && overflowX !== 'hidden') ? overflowX : false, y: (overflowY && overflowY !== 'hidden') ? overflowY : false }); return this; }, setPagePosition: function(x, y, animate) { var me = this, p, floatParentBox; if (Ext.isArray(x)) { y = x[1]; x = x[0]; } me.pageX = x; me.pageY = y; if (me.floating) { if (me.isContainedFloater()) { floatParentBox = me.floatParent.getTargetEl().getViewRegion(); if (Ext.isNumber(x) && Ext.isNumber(floatParentBox.left)) { x -= floatParentBox.left; } if (Ext.isNumber(y) && Ext.isNumber(floatParentBox.top)) { y -= floatParentBox.top; } } else { p = me.el.translateXY(x, y); x = p.x; y = p.y; } me.setPosition(x, y, animate); } else { p = me.el.translateXY(x, y); me.setPosition(p.x, p.y, animate); } return me; }, setPosition: function(x, y, animate) { var me = this, pos = me.beforeSetPosition.apply(me, arguments); if (pos && me.rendered) { x = pos.x; y = pos.y; if (animate) { if (x !== me.getLocalX() || y !== me.getLocalY()) { me.stopAnimation(); me.animate(Ext.apply({ duration: 1000, listeners: { afteranimate: Ext.Function.bind(me.afterSetPosition, me, [ x, y ]) }, to: { left: x, top: y } }, animate)); } } else { me.setLocalXY(x, y); me.afterSetPosition(x, y); } } return me; }, setScrollX: function(x, animate) { var scroller = this.getScrollable(); if (scroller) { scroller.scrollTo(x, null, animate); } }, setScrollY: function(y, animate) { var scroller = this.getScrollable(); if (scroller) { scroller.scrollTo(null, y, animate); } }, setSize: function(width, height) { var me = this, widthIsString, heightIsString, oldWidth = me.width, oldHeight = me.height; if (width && typeof width === 'object') { height = width.height; width = width.width; } if (typeof width === 'number') { me.width = Ext.Number.constrain(width, me.minWidth, me.maxWidth); } else if (width === null) { delete me.width; } else if (typeof width === 'string') { widthIsString = true; me.width = width; } if (typeof height === 'number') { me.height = Ext.Number.constrain(height, me.minHeight, me.maxHeight); } else if (height === null) { delete me.height; } else if (typeof height === 'string') { heightIsString = true; me.height = height; } if (me.rendered && me.isVisible()) { if (oldWidth !== me.width || oldHeight !== me.height) { if (me.liquidLayout || widthIsString || heightIsString) { me.el.setSize(me.width, me.height); } me.updateLayout(me._notAsLayoutRoot); } } return me; }, setStyle: function(prop, value) { var el = this.el || this.protoEl; el.setStyle(prop, value); return this; }, setUI: function(ui) { var me = this, uiCls = me.uiCls, activeUI = me.activeUI, classes; if (ui === activeUI) { return; } if (activeUI) { classes = me.removeClsWithUI(uiCls, true); if (classes.length) { me.removeCls(classes); } me.removeUIFromElement(); } else { me.uiCls = []; } me.ui = ui; me.activeUI = ui; me.addUIToElement(); classes = me.addClsWithUI(uiCls, true); if (classes.length) { me.addCls(classes); } if (me.rendered) { me.updateLayout(); } }, setVisible: function(visible) { return this[visible ? 'show' : 'hide'](); }, setHidden: function(hidden) { return this.setVisible(!hidden); }, setWidth: function(width) { return this.setSize(width); }, show: function(animateTarget, cb, scope) { var me = this, rendered = me.rendered; if (me.hierarchicallyHidden || (me.floating && !rendered && me.isHierarchicallyHidden())) { if (!rendered) { me.initHierarchyEvents(); } if (arguments.length > 1) { arguments[0] = null; me.pendingShow = arguments; } else { me.pendingShow = true; } } else if (rendered && me.isVisible()) { if (me.floating) { me.onFloatShow(); } } else { if (me.fireEvent('beforeshow', me) !== false) { me.hidden = false; delete this.getInherited().hidden; Ext.suspendLayouts(); if (!rendered && (me.autoRender || me.floating)) { me.doAutoRender(); rendered = me.rendered; } if (rendered) { me.beforeShow(); Ext.resumeLayouts(); me.onShow.apply(me, arguments); me.afterShow.apply(me, arguments); } else { Ext.resumeLayouts(true); } } else { me.onShowVeto(); } } return me; }, showAt: function(x, y, animate) { var me = this; if (!me.rendered && (me.autoRender || me.floating)) { me.x = x; me.y = y; return me.show(); } if (me.floating) { me.setPosition(x, y, animate); } else { me.setPagePosition(x, y, animate); } me.show(); }, showBy: function(cmp, pos, off) { var me = this; if (!me.floating) { Ext.log.warn('Using showBy on a non-floating component'); } if (me.floating && cmp) { me.alignTarget = cmp; if (pos) { me.defaultAlign = pos; } if (off) { me.alignOffset = off; } me.show(); if (!me.hidden) { me.alignTo(cmp, pos || me.defaultAlign, off || me.alignOffset); } } return me; }, suspendLayouts: function() { var me = this; if (!me.rendered) { return; } if (++me.layoutSuspendCount === 1) { me.suspendLayout = true; } }, unitizeBox: function(box) { return Ext.Element.unitizeBox(box); }, unmask: function() { (this.getMaskTarget() || this.el).unmask(); this.setMasked(false); }, unregisterFloatingItem: function(cmp) { var me = this; if (me.floatingDescendants) { me.floatingDescendants.unregister(cmp); } }, up: function(selector, limit) { var result = this.getRefOwner(), limitSelector = typeof limit === 'string', limitCount = typeof limit === 'number', limitComponent = limit && limit.isComponent, steps = 0; if (selector) { for (; result; result = result.getRefOwner()) { steps++; if (selector.isComponent) { if (result === selector) { return result; } } else { if (Ext.ComponentQuery.is(result, selector)) { return result; } } if (limitSelector && result.is(limit)) { return; } if (limitCount && steps === limit) { return; } if (limitComponent && result === limit) { return; } } } return result; }, update: function(htmlOrData, loadScripts, callback) { var me = this, isData = (me.tpl && !Ext.isString(htmlOrData)), scroller = me.getScrollable(), container = me.focusableContainer, sizeModel, doLayout, el; if (isData) { me.data = (htmlOrData && htmlOrData.isEntity) ? htmlOrData.getData(true) : htmlOrData; } else { me.html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData; } if (me.rendered) { sizeModel = me.getSizeModel(); doLayout = sizeModel.width.shrinkWrap || sizeModel.height.shrinkWrap; if (me.isContainer) { el = me.layout.getRenderTarget(); doLayout = doLayout || me.items.items.length > 0; } else { el = me.touchScroll ? me.getScrollerEl() : me.getTargetEl(); } if (isData) { me.tpl[me.tplWriteMode](el, me.data || {}); } else { el.setHtml(me.html, loadScripts, callback); } if (doLayout) { me.updateLayout(); } if (scroller) { scroller.refresh(true); } if (container) { container.onFocusableChildUpdate(me); } } }, setHtml: function(html) { this.update(html); }, applyData: function(data) { this.update(data); }, updateBox: function(box) { this.setSize(box.width, box.height); this.setPagePosition(box.x, box.y); return this; }, _asLayoutRoot: { isRoot: true }, _notAsLayoutRoot: { isRoot: false }, updateLayout: function(options) { var me = this, defer, lastBox = me.lastBox, isRoot = options && options.isRoot; if (lastBox) { lastBox.invalid = true; } if (!me.rendered || me.layoutSuspendCount || me.suspendLayout) { return; } if (me.hidden) { Ext.Component.cancelLayout(me); } else if (typeof isRoot !== 'boolean') { isRoot = me.isLayoutRoot(); } if (isRoot || !me.ownerLayout || !me.ownerLayout.onContentChange(me)) { if (!me.isLayoutSuspended()) { defer = (options && options.hasOwnProperty('defer')) ? options.defer : me.deferLayouts; Ext.Component.updateLayout(me, defer); } } }, updateMaxHeight: function(maxHeight, oldMaxHeight) { this.changeConstraint(maxHeight, oldMaxHeight, 'min', 'max-height', 'height'); }, updateMaxWidth: function(maxWidth, oldMaxWidth) { this.changeConstraint(maxWidth, oldMaxWidth, 'min', 'max-width', 'width'); }, updateMinHeight: function(minHeight, oldMinHeight) { this.changeConstraint(minHeight, oldMinHeight, 'max', 'min-height', 'height'); }, updateMinWidth: function(minWidth, oldMinWidth) { this.changeConstraint(minWidth, oldMinWidth, 'max', 'min-width', 'width'); }, getAnchorToXY: function(el, anchor, local, mySize) { return el.getAnchorXY(anchor, local, mySize); }, getBorderPadding: function() { return this.el.getBorderPadding(); }, getLocalX: function() { return this.el.getLocalX(); }, getLocalXY: function() { return this.el.getLocalXY(); }, getLocalY: function() { return this.el.getLocalY(); }, getX: function() { return this.el.getX(); }, getXY: function() { return this.el.getXY(); }, getY: function() { return this.el.getY(); }, setLocalX: function(x) { this.el.setLocalX(x); }, setLocalXY: function(x, y) { this.el.setLocalXY(x, y); }, setLocalY: function(y) { this.el.setLocalY(y); }, setX: function(x, animate) { this.el.setX(x, animate); }, setXY: function(xy, animate) { this.el.setXY(xy, animate); }, setY: function(y, animate) { this.el.setY(y, animate); }, privates: { addOverCls: function() { var me = this; if (!me.disabled) { me.el.addCls(me.overCls); } }, addUIToElement: function() { var me = this, baseClsUI = me.baseCls + '-' + me.ui, childEls, childElName, el, suffix; me.addCls(baseClsUI); if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { baseClsUI += '-'; childEls = me.getChildEls(); for (childElName in childEls) { suffix = childEls[childElName].frame; if (suffix && suffix !== true) { el = me[childElName]; if (el) { el.addCls(baseClsUI + suffix); } } } } }, changeConstraint: function(newValue, oldValue, constrainMethod, styleName, sizeName) { var me = this, size = me[sizeName]; if (newValue != null && typeof size === 'number') { me[sizeName] = Math[constrainMethod](size, newValue); } if (me.liquidLayout) { if (newValue != null) { me.setStyle(styleName, newValue + 'px'); } else if (oldValue) { me.setStyle(styleName, ''); } } if (me.rendered) { me.updateLayout(); } }, constructPlugin: function(plugin) { var me = this; if (typeof plugin === 'string') { plugin = Ext.PluginManager.create({}, plugin, me); } else { plugin = Ext.PluginManager.create(plugin, null, me); } return plugin; }, constructPlugins: function() { var me = this, plugins = me.plugins, result, i, len; if (plugins) { result = []; result.processed = true; if (!Ext.isArray(plugins)) { plugins = [ plugins ]; } for (i = 0 , len = plugins.length; i < len; i++) { result[i] = me.constructPlugin(plugins[i]); } } me.pluginsInitialized = true; return result; }, detachFromBody: function() { Ext.getDetachedBody().appendChild(this.el); Ext.Component.cancelLayout(this); this.isDetached = true; }, doAddListener: function(ename, fn, scope, options, order, caller, manager) { var me = this, listeners, option, eventOptions, elementName, element; if (Ext.isObject(fn) || (options && options.element)) { if (options.element) { elementName = options.element; listeners = {}; listeners[ename] = fn; if (scope) { listeners.scope = scope; } eventOptions = me.$elementEventOptions; for (option in options) { if (eventOptions[option]) { listeners[option] = options[option]; } } } else { listeners = fn; elementName = ename; } element = me[elementName]; if (element && element.isObservable) { me.mon(element, listeners); } else { me.afterRenderEvents = me.afterRenderEvents || {}; if (!me.afterRenderEvents[elementName]) { me.afterRenderEvents[elementName] = []; } me.afterRenderEvents[elementName].push(listeners); } return; } me.mixins.observable.doAddListener.call(me, ename, fn, scope, options, order, caller, manager); }, fireHierarchyEvent: function(eventName) { var globalEvents = Ext.GlobalEvents; if (globalEvents.hasListeners[eventName]) { globalEvents.fireEvent(eventName, this); } }, getActionEl: function() { return this.el; }, getAutoId: function() { this.autoGenId = true; return ++Ext.Component.AUTO_ID; }, getContentTarget: function() { return this.el; }, getDragEl: function() { return this.el; }, getOverflowEl: function() { return this.getTargetEl(); }, getOverflowStyle: function() { var me = this, scroller = me.getScrollable(), flags = me._scrollFlags, x, y, scrollFlags; if (scroller) { x = scroller.getX(); if (x === true) { x = 'auto'; } y = scroller.getY(); if (y === true) { y = 'auto'; } scrollFlags = flags[x][y]; } else { scrollFlags = flags.none; } me.scrollFlags = scrollFlags; return { overflowX: scrollFlags.overflowX, overflowY: scrollFlags.overflowY }; }, getPlugins: function() { var plugins = this.plugins; plugins = (plugins && plugins.processed) ? plugins : this.constructPlugins(); return plugins || null; }, getProxy: function() { var me = this, target; if (!me.proxy) { target = Ext.getBody(); me.proxy = me.el.createProxy(Ext.baseCSSPrefix + 'proxy-el', target, true); } return me.proxy; }, getScrollerEl: function() { var me = this; return me.scrollerEl || (me.scrollerEl = me.componentLayout.getScrollerEl() || me.getOverflowEl().child(me.scrollerSelector)); }, getTargetEl: function() { return this.frameBody || this.el; }, getTdCls: function() { return Ext.baseCSSPrefix + this.getTdType() + '-' + this.ui + '-cell'; }, getTdType: function() { return this.xtype; }, getTpl: function(name) { return Ext.XTemplate.getTpl(this, name); }, initCls: function() { var me = this, cls = [ me.baseCls ], targetCls = me.getComponentLayout().targetCls; if (targetCls) { cls.push(targetCls); } 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; } return cls; }, initDraggable: function() { var me = this, dragTarget = (me.resizer && me.resizer.el !== me.el) ? me.resizerComponent = new Ext.Component({ ariaRole: 'presentation', el: me.resizer.el, rendered: true, container: me.container }) : me, ddConfig = Ext.applyIf({ el: dragTarget.getDragEl(), constrainTo: (me.constrain || me.draggable.constrain) ? (me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.container)) : undefined }, me.draggable); if (me.constrain || me.constrainDelegate) { ddConfig.constrain = me.constrain; ddConfig.constrainDelegate = me.constrainDelegate; } me.dd = new Ext.util.ComponentDragger(dragTarget, ddConfig); }, initPadding: function(targetEl) { var me = this, padding = me.padding; if (padding != null) { if (me.touchScroll || (me.layout && me.layout.managePadding && me.contentPaddingProperty === 'padding')) { targetEl.setStyle('padding', 0); } else { targetEl.setStyle('padding', this.unitizeBox((padding === true) ? 5 : padding)); } } }, initPlugin: function(plugin) { plugin.init(this); return plugin; }, initResizable: function(resizable) { var me = this; resizable = Ext.apply({ target: me, dynamic: false, constrainTo: (me.constrain || (resizable && resizable.constrain)) ? (me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.container)) : undefined, handles: me.resizeHandles }, resizable); resizable.target = me; me.resizer = new Ext.resizer.Resizer(resizable); }, initStyles: function(targetEl) { var me = this, margin = me.margin, border = me.border, cls = me.cls, style = me.style, x = me.x, y = me.y, liquidLayout = me.liquidLayout, width, height; me.initPadding(targetEl); if (margin != null) { targetEl.setStyle('margin', this.unitizeBox((margin === true) ? 5 : margin)); } if (border != null) { me.setBorder(border, targetEl); } if (cls && cls !== me.initialCls) { targetEl.addCls(cls); me.cls = me.initialCls = null; } if (style && style !== me.initialStyle) { targetEl.setStyle(style); me.style = me.initialStyle = null; } if (x != null) { targetEl.setStyle(me.horizontalPosProp, (typeof x === 'number') ? (x + 'px') : x); } if (y != null) { targetEl.setStyle('top', (typeof y === 'number') ? (y + 'px') : y); } if (!me.ownerCt || me.floating) { if (Ext.scopeCss) { targetEl.addCls(me.rootCls); } targetEl.addCls(me.borderBoxCls); } if (liquidLayout || !me.getFrameInfo()) { width = me.width; height = me.height; if (width != null) { if (typeof width === 'number') { targetEl.setStyle('width', width + 'px'); } else { targetEl.setStyle('width', width); } } if (height != null) { if (typeof height === 'number') { targetEl.setStyle('height', height + 'px'); } else { targetEl.setStyle('height', height); } } } }, isContainedFloater: function() { return (this.floating && this.floatParent); }, isDescendant: function(ancestor) { if (ancestor.isContainer) { for (var c = this.ownerCt; c; c = c.ownerCt) { if (c === ancestor) { return true; } } } return false; }, owns: function(element) { var result = false, cmp; if (element.isEvent) { element = element.target; } else if (element.isElement) { element = element.dom; } cmp = Ext.Component.fromElement(element); if (cmp) { result = (cmp === this) || (!!cmp.up(this)); } return result; }, parseBox: function(box) { return Ext.Element.parseBox(box); }, reattachToBody: function() { this.isDetached = false; }, refreshScroll: function() { var scroller = this.getScrollable(); if (scroller) { scroller.refresh(); } }, removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope) { var me = this, element = managedListener.options ? managedListener.options.element : null; if (element) { element = me[element]; if (element && element.un) { if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) { element.un(managedListener.ename, managedListener.fn, managedListener.scope); if (!isClear) { Ext.Array.remove(me.managedListeners, managedListener); } } } } else { return me.mixins.observable.removeManagedListenerItem.apply(me, arguments); } }, removeOverCls: function() { this.el.removeCls(this.overCls); }, removePlugin: function(plugin) { Ext.Array.remove(this.plugins, plugin); plugin.destroy(); }, removeUIFromElement: function() { var me = this, baseClsUI = me.baseCls + '-' + me.ui, childEls, childElName, el, suffix; me.removeCls(baseClsUI); if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { baseClsUI += '-'; childEls = me.getChildEls(); for (childElName in childEls) { suffix = childEls[childElName].frame; if (suffix && suffix !== true) { el = me[childElName]; if (el) { el.removeCls(baseClsUI + suffix); } } } } }, setComponentLayout: function(layout) { var currentLayout = this.componentLayout; if (currentLayout && currentLayout.isLayout && currentLayout !== layout) { currentLayout.setOwner(null); } this.componentLayout = layout; layout.setOwner(this); }, setHiddenState: function(hidden) { var me = this, inheritedState = me.getInherited(), zIndexManager = me.zIndexManager; me.hidden = hidden; if (hidden) { inheritedState.hidden = true; } else { delete inheritedState.hidden; } if (zIndexManager) { zIndexManager.onComponentShowHide(me); } }, setupProtoEl: function() { var cls = this.initCls(); this.protoEl.addCls(cls); }, wrapPrimaryEl: function(dom) { var me = this, el = me.el; if (!el || !el.isElement) { me.el = Ext.get(dom); } if (me.floating) { this.mixins.floating.constructor.call(this); } } }, deprecated: { 5: { methods: { addClass: 'addCls', doComponentLayout: function() { this.updateLayout(); return this; }, removeClass: 'removeCls', forceComponentLayout: 'updateLayout', setDocked: 'setDock' } } } }, function(Component) { (Component.prototype.$elementEventOptions = Ext.Object.chain(Ext.Element.prototype.$eventOptions)).element = 1; Component.createAlias({ on: 'addListener', prev: 'previousSibling', next: 'nextSibling' }); Ext.resumeLayouts = function(flush) { Component.resumeLayouts(flush); }; Ext.suspendLayouts = function() { Component.suspendLayouts(); }; Ext.batchLayouts = function(fn, scope) { Component.suspendLayouts(); fn.call(scope); Component.resumeLayouts(true); }; Ext.setGlyphFontFamily = function(fontFamily) { Ext._glyphFontFamily = fontFamily; }; Component.hierarchyEventSource = Component.prototype.hierarchyEventSource = Ext.GlobalEvents; var metaTags = document.getElementsByTagName('head')[0].getElementsByTagName('meta'), len = metaTags.length, i, hasViewport; for (i = 0; i < len; i++) { if (metaTags[i].name === 'viewport') { hasViewport = true; } } if (!hasViewport) { Ext.log.warn('Ext JS requires a viewport meta tag in order to function correctly on mobile devices. Please add the following tag to the of your html page: \n '); } }); Ext.define('Ext.layout.container.border.Region', { override: 'Ext.Component', initBorderRegion: function() { var me = this; if (!me._borderRegionInited) { me._borderRegionInited = true; me.addStateEvents([ 'changeregion', 'changeweight' ]); Ext.override(me, { getState: function() { var state = me.callParent(); state = me.addPropertyToState(state, 'region'); state = me.addPropertyToState(state, 'weight'); return state; } }); } }, getOwningBorderContainer: function() { var layout = this.getOwningBorderLayout(); return layout && layout.owner; }, getOwningBorderLayout: function() { var layout = this.ownerLayout; return (layout && layout.isBorderLayout) ? layout : null; }, setRegion: function(region) { var me = this, borderLayout, old = me.region; if (typeof region !== 'string') { Ext.Error.raise('Use setBox to set the size or position of a component.'); } if (region !== old) { borderLayout = me.getOwningBorderLayout(); if (borderLayout) { var regionFlags = borderLayout.regionFlags[region], placeholder = me.placeholder, splitter = me.splitter, owner = borderLayout.owner, regionMeta = borderLayout.regionMeta, collapsed = me.collapsed || me.floated, delta, items, index; if (me.fireEventArgs('beforechangeregion', [ me, region ]) === false) { return old; } Ext.suspendLayouts(); me.region = region; Ext.apply(me, regionFlags); if (me.updateCollapseTool) { me.updateCollapseTool(); } if (splitter) { Ext.apply(splitter, regionFlags); splitter.updateOrientation(); items = owner.items; index = items.indexOf(me); if (index >= 0) { delta = regionMeta[region].splitterDelta; if (items.getAt(index + delta) !== splitter) { items.remove(splitter); index = items.indexOf(me); if (delta > 0) { ++index; } items.insert(index, splitter); } } } if (placeholder) { if (collapsed) { me.expand(false); } owner.remove(placeholder); me.placeholder = null; if (collapsed) { me.collapse(null, false); } } owner.updateLayout(); Ext.resumeLayouts(true); me.fireEventArgs('changeregion', [ me, old ]); } else { me.region = region; } } return old; }, setWeight: function(weight) { var me = this, ownerCt = me.getOwningBorderContainer(), placeholder = me.placeholder, old = me.weight; if (weight !== old) { if (me.fireEventArgs('beforechangeweight', [ me, weight ]) !== false) { me.weight = weight; if (placeholder) { placeholder.weight = weight; } if (ownerCt) { ownerCt.updateLayout(); } me.fireEventArgs('changeweight', [ me, old ]); } } return old; } }, function(Component) { var proto = Component.prototype; proto.setBorderRegion = proto.setRegion; proto.setRegionWeight = proto.setWeight; }); Ext.define('Ext.overrides.app.domain.Component', { override: 'Ext.app.domain.Component', requires: [ 'Ext.Component' ] }, function(ComponentDomain) { ComponentDomain.monitor(Ext.Component); }); Ext.define('Ext.app.EventBus', { singleton: true, requires: [ 'Ext.app.domain.Component' ], constructor: function() { var me = this, domains = Ext.app.EventDomain.instances; me.callParent(); me.domains = domains; me.bus = domains.component.bus; }, control: function(selectors, controller) { return this.domains.component.listen(selectors, controller); }, listen: function(to, controller) { var domains = this.domains, domain; for (domain in to) { if (to.hasOwnProperty(domain)) { domains[domain].listen(to[domain], controller); } } }, unlisten: function(controllerId) { var domains = Ext.app.EventDomain.instances, domain; for (domain in domains) { domains[domain].unlisten(controllerId); } } }); Ext.define('Ext.app.domain.Global', { extend: 'Ext.app.EventDomain', requires: [ 'Ext.GlobalEvents' ], singleton: true, type: 'global', constructor: function() { var me = this; me.callParent(); me.monitor(Ext.GlobalEvents); }, listen: function(listeners, controller) { this.callParent([ { global: listeners }, controller ]); }, match: Ext.returnTrue }); Ext.define('Ext.app.BaseController', { requires: [ 'Ext.app.EventBus', 'Ext.app.domain.Global' ], uses: [ 'Ext.app.domain.Controller' ], mixins: [ 'Ext.mixin.Observable' ], isController: true, config: { id: null, control: null, listen: null, routes: null, before: null }, constructor: function(config) { var me = this; Ext.apply(me, config); delete me.control; delete me.listen; me.eventbus = Ext.app.EventBus; me.mixins.observable.constructor.call(me, config); me.ensureId(); }, applyListen: function(listen) { if (Ext.isObject(listen)) { listen = Ext.clone(listen); } return listen; }, applyControl: function(control) { if (Ext.isObject(control)) { control = Ext.clone(control); } return control; }, updateControl: function(control) { this.ensureId(); if (control) { this.control(control); } }, updateListen: function(listen) { this.ensureId(); if (listen) { this.listen(listen); } }, updateRoutes: function(routes) { if (routes) { var me = this, befores = me.getBefore() || {}, Router = Ext.app.route.Router, url, config, method; for (url in routes) { config = routes[url]; if (Ext.isString(config)) { config = { action: config }; } method = config.action; if (!config.before) { config.before = befores[method]; } else if (befores[method]) { Ext.log.warn('You have a before method configured on a route ("' + url + '") and in the before object property also in the "' + me.self.getName() + '" controller. Will use the before method in the route and disregard the one in the before property.'); } Router.connect(url, config, me); } } }, isActive: function() { return true; }, control: function(selectors, listeners, controller) { var me = this, ctrl = controller, obj; if (Ext.isString(selectors)) { obj = {}; obj[selectors] = listeners; } else { obj = selectors; ctrl = listeners; } me.eventbus.control(obj, ctrl || me); }, listen: function(to, controller) { this.eventbus.listen(to, controller || this); }, destroy: function() { var me = this, bus = me.eventbus; Ext.app.route.Router.disconnectAll(me); if (bus) { bus.unlisten(me); me.eventbus = null; } me.clearListeners(); me.callParent(); }, redirectTo: function(token, force) { if (token.isModel) { token = token.toUrl(); } if (!force) { var currentToken = Ext.util.History.getToken(); if (currentToken === token) { return false; } } else { Ext.app.route.Router.onStateChange(token); } Ext.util.History.add(token); return true; } }); Ext.define('Ext.app.Util', {}, function() { Ext.apply(Ext.app, { namespaces: { Ext: {} }, addNamespaces: function(namespace) { var namespaces = Ext.app.namespaces, i, l; if (!Ext.isArray(namespace)) { namespace = [ namespace ]; } for (i = 0 , l = namespace.length; i < l; i++) { namespaces[namespace[i]] = true; } }, clearNamespaces: function() { Ext.app.namespaces = {}; }, getNamespace: function(className) { var namespaces = Ext.apply({}, Ext.ClassManager.paths, Ext.app.namespaces), deepestPrefix = '', prefix; for (prefix in namespaces) { if (namespaces.hasOwnProperty(prefix) && prefix.length > deepestPrefix.length && (prefix + '.' === className.substring(0, prefix.length + 1))) { deepestPrefix = prefix; } } return deepestPrefix === '' ? undefined : deepestPrefix; } }); Ext.getNamespace = Ext.app.getNamespace; }); Ext.define('Ext.util.CollectionKey', { mixins: [ 'Ext.mixin.Identifiable' ], isCollectionKey: true, observerPriority: -200, config: { collection: null, keyFn: null, property: null, rootProperty: null, unique: true }, generation: 0, map: null, mapRebuilds: 0, constructor: function(config) { this.initConfig(config); if (!Ext.isFunction(this.getKey)) { Ext.Error.raise('CollectionKey requires a keyFn or property config'); } }, get: function(key) { var map = this.map || this.getMap(); return map[key] || null; }, clear: function() { this.map = null; }, getRootProperty: function() { var me = this, root = this.callParent(); return root !== null ? root : me.getCollection().getRootProperty(); }, indexOf: function(key, startAt) { var map = this.map || this.getMap(), item = map[key], collection = this.getCollection(), length = collection.length, i, index, items, n; if (!item) { return -1; } if (startAt === undefined) { startAt = -1; } if (item instanceof Array) { items = item; index = length; for (n = items.length; n-- > 0; ) { i = collection.indexOf(items[n]); if (i < index && i > startAt) { index = i; } } if (index === length) { return -1; } } else { index = collection.indexOf(item); } return (index > startAt) ? index : -1; }, updateKey: function(item, oldKey) { var me = this, map = me.map, bucket, index; if (map) { bucket = map[oldKey]; if (bucket instanceof Array) { index = Ext.Array.indexOf(bucket, item); if (index >= 0) { if (bucket.length > 2) { bucket.splice(index, 1); } else { map[oldKey] = bucket[1 - index]; } } } else if (bucket) { if (me.getUnique() && bucket !== item) { Ext.Error.raise('Incorrect oldKey "' + oldKey + '" for item with newKey "' + me.getKey(item) + '"'); } delete map[oldKey]; } me.add([ item ]); } }, onCollectionAdd: function(collection, add) { if (this.map) { this.add(add.items); } }, onCollectionItemChange: function(collection, details) { this.map = null; }, onCollectionRefresh: function() { this.map = null; }, onCollectionRemove: function(collection, remove) { var me = this, map = me.map, items = remove.items, length = items.length, i, item, key; if (map) { if (me.getUnique() && length < collection.length / 2) { for (i = 0; i < length; ++i) { key = me.getKey(item = items[i]); delete map[key]; } } else { me.map = null; } } }, add: function(items) { var me = this, map = me.map, bucket, i, item, key, length, unique; length = items.length; unique = me.getUnique(); for (i = 0; i < length; ++i) { key = me.getKey(item = items[i]); if (unique || !(key in map)) { map[key] = item; } else { if (!((bucket = map[key]) instanceof Array)) { map[key] = bucket = [ bucket ]; } bucket.push(item); } } }, applyKeyFn: function(keyFn) { if (Ext.isString(keyFn)) { this.getKey = function(item) { return item[keyFn](); }; } else { this.getKey = keyFn; } }, updateProperty: function(property) { var root = this.getRootProperty(); this.getKey = function(item) { return (root ? item[root] : item)[property]; }; }, getMap: function() { var me = this, map = me.map; if (!map) { me.map = map = {}; me.keysByItemKey = {}; ++me.mapRebuilds; me.add(me.getCollection().items); } return map; }, updateCollection: function(collection) { collection.addObserver(this); }, clone: function() { return new Ext.util.CollectionKey(this.getCurrentConfig()); } }); Ext.define('Ext.util.Grouper', { extend: 'Ext.util.Sorter', isGrouper: true, config: { groupFn: null, sortProperty: null }, constructor: function(config) { if (config) { if (config.getGroupString) { Ext.Error.raise("Cannot set getGroupString - use groupFn instead"); } } this.callParent(arguments); }, getGroupString: function(item) { var group = this._groupFn(item); return (group != null) ? String(group) : ''; }, sortFn: function(item1, item2) { var me = this, lhs = me._groupFn(item1), rhs = me._groupFn(item2), property = me._sortProperty, root = me._root, sorterFn = me._sorterFn, transform = me._transform; if (lhs === rhs) { return 0; } if (property || sorterFn) { if (sorterFn) { return sorterFn.call(this, item1, item2); } if (root) { item1 = item1[root]; item2 = item2[root]; } lhs = item1[property]; rhs = item2[property]; if (transform) { lhs = transform(lhs); rhs = transform(rhs); } } return (lhs > rhs) ? 1 : (lhs < rhs ? -1 : 0); }, standardGroupFn: function(item) { var root = this._root; return (root ? item[root] : item)[this._property]; }, updateSorterFn: function() {}, updateProperty: function() { if (!this.getGroupFn()) { this.setGroupFn(this.standardGroupFn); } } }); Ext.define('Ext.util.Collection', { mixins: [ 'Ext.mixin.Observable' ], requires: [ 'Ext.util.CollectionKey', 'Ext.util.Filter', 'Ext.util.Sorter', 'Ext.util.Grouper' ], uses: [ 'Ext.util.SorterCollection', 'Ext.util.FilterCollection', 'Ext.util.GroupCollection' ], isCollection: true, config: { autoFilter: true, autoSort: true, autoGroup: true, decoder: null, extraKeys: null, filters: null, grouper: null, groups: null, rootProperty: null, sorters: null, multiSortLimit: 3, defaultSortDirection: 'ASC', source: null }, generation: 0, indices: null, indexRebuilds: 0, updating: 0, grouped: false, sorted: false, filtered: false, $endUpdatePriority: 1001, constructor: function(config) { var me = this; me.items = []; me.map = {}; me.length = 0; if (config && config.keyFn) { me.getKey = config.keyFn; } me.mixins.observable.constructor.call(me, config); }, destroy: function() { var me = this, filters = me._filters, sorters = me._sorters, groups = me._groups; if (filters) { filters.destroy(); me._filters = null; } if (sorters) { sorters.destroy(); me._sorters = null; } if (groups) { groups.destroy(); me._groups = null; } me.setSource(null); me.observers = me.items = me.map = null; }, add: function(item) { var me = this, items = me.decodeItems(arguments, 0), ret = items; if (items.length) { me.requestedIndex = me.length; me.splice(me.length, 0, items); delete me.requestedIndex; ret = (items.length === 1) ? items[0] : items; } return ret; }, replaceAll: function() { var me = this, len = me.length, ret, items; if (len === 0) { return me.add.apply(me, arguments); } items = me.decodeItems(arguments, 0); ret = items; if (items.length) { me.splice(0, me.length, items); ret = (items.length === 1) ? items[0] : items; } else { me.removeAll(); } return ret; }, aggregate: function(property, operation, begin, end, scope) { var me = this, args = Ext.Array.slice(arguments); args.unshift(me.items); return me.aggregateItems.apply(me, args); }, aggregateByGroup: function(property, operation, scope) { var groups = this.getGroups(); return this.aggregateGroups(groups, property, operation, scope); }, aggregateItems: function(items, property, operation, begin, end, scope) { var me = this, range = Ext.Number.clipIndices(items.length, [ begin, end ]), subsetRequested = (begin !== 0 && end !== items.length), i, j, rangeLen, root, value, values, valueItems; begin = range[0]; end = range[1]; if (!Ext.isFunction(operation)) { operation = me._aggregators[operation]; return operation.call(me, items, begin, end, property, me.getRootProperty()); } root = me.getRootProperty(); values = new Array(rangeLen); valueItems = subsetRequested ? new Array(rangeLen) : items; for (i = begin , j = 0; i < end; ++i , j++) { if (subsetRequested) { valueItems[j] = value = items[i]; } values[j] = (root ? value[root] : value)[property]; } return operation.call(scope || me, items, values, 0); }, aggregateGroups: function(groups, property, operation, scope) { var items = groups.items, len = items.length, callDirect = !Ext.isFunction(operation), out = {}, i, group, result; for (i = 0; i < len; ++i) { group = items[i]; if (!callDirect) { result = this.aggregateItems(group.items, property, operation, null, null, scope); } else { result = group[operation](property); } out[group.getGroupKey()] = result; } return out; }, beginUpdate: function() { if (!this.updating++) { this.notify('beginupdate'); } }, clear: function() { var me = this, generation = me.generation, ret = generation ? me.items : [], extraKeys, indexName; if (generation) { me.items = []; me.length = 0; me.map = {}; me.indices = {}; me.generation++; extraKeys = me.getExtraKeys(); if (extraKeys) { for (indexName in extraKeys) { extraKeys[indexName].clear(); } } } return ret; }, clone: function() { var me = this, copy = new me.self(me.initialConfig); copy.add(me.items); return copy; }, collect: function(property, root, allowNull) { var items = this.items, length = items.length, map = {}, ret = [], i, strValue, value; for (i = 0; i < length; ++i) { value = items[i]; value = (root ? value[root] : value)[property]; strValue = String(value); if ((allowNull || !Ext.isEmpty(value)) && !map[strValue]) { map[strValue] = 1; ret.push(value); } } return ret; }, contains: function(item) { var ret = false, key; if (item != null) { key = this.getKey(item); ret = this.map[key] === item; } return ret; }, containsKey: function(key) { return key in this.map; }, createFiltered: function(property, value, anyMatch, caseSensitive, exactMatch) { var me = this, ret = new me.self(me.initialConfig), root = me.getRootProperty(), items = me.items, length, i, filters, fn, scope; if (Ext.isFunction(property)) { fn = property; scope = value; } else { if (Ext.isString(property)) { filters = [ new Ext.util.Filter({ property: property, value: value, root: root, anyMatch: anyMatch, caseSensitive: caseSensitive, exactMatch: exactMatch }) ]; } else if (property instanceof Ext.util.Filter) { filters = [ property ]; property.setRoot(root); } else if (Ext.isArray(property)) { filters = property.slice(0); for (i = 0 , length = filters.length; i < length; ++i) { filters[i].setRoot(root); } } fn = Ext.util.Filter.createFilterFn(filters); } scope = scope || me; for (i = 0 , length = items.length; i < length; i++) { if (fn.call(scope, items[i])) { ret.add(items[i]); } } return ret; }, filterBy: function(fn, scope) { return this.createFiltered(fn, scope); }, each: function(fn, scope) { var items = this.items, len = items.length, i, ret; if (len) { scope = scope || this; items = items.slice(0); for (i = 0; i < len; i++) { ret = fn.call(scope, items[i], i, len); if (ret === false) { break; } } } return ret; }, eachKey: function(fn, scope) { var me = this, items = me.items, len = items.length, i, item, key, ret; if (len) { scope = scope || me; items = items.slice(0); for (i = 0; i < len; i++) { key = me.getKey(item = items[i]); ret = fn.call(scope, key, item, i, len); if (ret === false) { break; } } } return ret; }, endUpdate: function() { if (!--this.updating) { this.notify('endupdate'); } }, find: function(property, value, start, startsWith, endsWith, ignoreCase) { if (Ext.isEmpty(value, false)) { return null; } var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase), root = this.getRootProperty(); return this.findBy(function(item) { return item && regex.test((root ? item[root] : item)[property]); }, null, start); }, findBy: function(fn, scope, start) { var me = this, items = me.items, len = items.length, i, item, key; scope = scope || me; for (i = start || 0; i < len; i++) { key = me.getKey(item = items[i]); if (fn.call(scope, item, key)) { return items[i]; } } return null; }, findIndex: function(property, value, start, startsWith, endsWith, ignoreCase) { var item = this.find(property, value, start, startsWith, endsWith, ignoreCase); return item ? this.indexOf(item) : -1; }, findIndexBy: function(fn, scope, start) { var item = this.findBy(fn, scope, start); return item ? this.indexOf(item) : -1; }, first: function(grouped) { var groups = grouped ? this.getGroups() : undefined; return groups ? this.aggregateGroups(groups, null, 'first') : this.items[0]; }, last: function(grouped) { var groups = grouped ? this.getGroups() : undefined; return groups ? this.aggregateGroups(groups, null, 'last') : this.items[this.length - 1]; }, get: function(key) { return this.map[key]; }, getAt: function(index) { return this.items[index]; }, getByKey: function(key) { return this.map[key]; }, getCount: function() { return this.length; }, getKey: function(item) { var id = item.id; return (id === 0 || id) ? id : ((id = item._id) === 0 || id) ? id : item.getId(); }, getRange: function(begin, end) { var items = this.items, length = items.length, range; if (begin > end) { Ext.Error.raise('Inverted range passed to Collection.getRange: [' + begin + ',' + end + ']'); } if (!length) { range = []; } else { range = Ext.Number.clipIndices(length, [ begin, end ]); range = items.slice(range[0], range[1]); } return range; }, getValues: function(property, root, start, end) { var items = this.items, range = Ext.Number.clipIndices(items.length, [ start, end ]), ret = [], i, value; for (i = range[0] , end = range[1]; i < end; ++i) { value = items[i]; value = (root ? value[root] : value)[property]; ret.push(value); } return ret; }, indexOf: function(item) { if (!item) { return -1; } var key = this.getKey(item); return this.indexOfKey(key); }, indexOfKey: function(key) { var me = this, indices = me.indices; if (key in me.map) { if (!indices) { indices = me.getIndices(); } return indices[key]; } return -1; }, insert: function(index, item) { var me = this, items = me.decodeItems(arguments, 1), ret = items; if (items.length) { me.requestedIndex = index; me.splice(index, 0, items); delete me.requestedIndex; ret = (items.length === 1) ? items[0] : items; } return ret; }, itemChanged: function(item, modified, oldKey, meta) { var me = this, keyChanged = oldKey === 0 || !!oldKey, filtered = me.filtered && me.getAutoFilter(), filterChanged = false, itemMovement = 0, items = me.items, last = me.length - 1, sorted = me.sorted && last > 0 && me.getAutoSort(), source = me.getSource(), toAdd, toRemove = 0, index, itemFiltered = false, newIndex, wasFiltered = false, details, newKey, sortFn; if (source && !source.updating) { source.itemChanged(item, modified, oldKey, meta); } else { newKey = me.getKey(item); if (filtered) { index = me.indexOfKey(keyChanged ? oldKey : newKey); wasFiltered = (index < 0); itemFiltered = me.isItemFiltered(item); filterChanged = (wasFiltered !== itemFiltered); } if (filterChanged) { if (itemFiltered) { toRemove = [ item ]; newIndex = -1; } else { toAdd = [ item ]; newIndex = me.length; } } else if (sorted && !itemFiltered) { if (!filtered) { index = me.indexOfKey(keyChanged ? oldKey : newKey); } sortFn = me.getSortFn(); if (index && sortFn(items[index - 1], items[index]) > 0) { itemMovement = -1; newIndex = Ext.Array.binarySearch(items, item, 0, index, sortFn); } else if (index < last && sortFn(items[index], items[index + 1]) > 0) { itemMovement = 1; newIndex = Ext.Array.binarySearch(items, item, index + 1, sortFn); } if (itemMovement) { toAdd = [ item ]; } } details = { item: item, key: newKey, index: newIndex, filterChanged: filterChanged, keyChanged: keyChanged, indexChanged: !!itemMovement, filtered: itemFiltered, oldIndex: index, newIndex: newIndex, wasFiltered: wasFiltered, meta: meta }; if (keyChanged) { details.oldKey = oldKey; } if (modified) { details.modified = modified; } me.beginUpdate(); me.notify('beforeitemchange', [ details ]); if (keyChanged) { me.updateKey(item, oldKey); } if (toAdd || toRemove) { me.splice(newIndex, toRemove, toAdd); } if (itemMovement > 0) { details.newIndex--; } else if (itemMovement < 0) { details.oldIndex++; } me.notify(itemFiltered ? 'filtereditemchange' : 'itemchange', [ details ]); me.endUpdate(); } }, remove: function(item) { var me = this, items = me.decodeRemoveItems(arguments, 0), length = me.length; me.splice(0, items); return length - me.length; }, removeAll: function() { var me = this, length = me.length; if (me.generation && length) { me.splice(0, length); } return me; }, removeAt: function(index, count) { var me = this, length = me.length, Num = Ext.Number, range = Num.clipIndices(length, [ index, (count === undefined) ? 1 : count ], Num.Clip.COUNT), n = range[0], removeCount = range[1] - n, item = (removeCount === 1) && me.getAt(n), removed; me.splice(n, removeCount); removed = me.length - length; return (item && removed) ? item : removed; }, removeByKey: function(key) { var item = this.getByKey(key); if (!item || !this.remove(item)) { return false; } return item; }, replace: function(item) { var index = this.indexOf(item); if (index === -1) { this.add(item); } else { this.insert(index, item); } }, splice: function(index, toRemove, toAdd) { var me = this, autoSort = me.sorted && me.getAutoSort(), map = me.map, items = me.items, length = me.length, removeItems = (toRemove instanceof Array) ? me.decodeRemoveItems(toRemove) : null, isRemoveCount = !removeItems, Num = Ext.Number, range = Num.clipIndices(length, [ index, isRemoveCount ? toRemove : 0 ], Num.Clip.COUNT), begin = range[0], end = range[1], removeCount = end - begin, newItems = me.decodeItems(arguments, 2), newCount = newItems ? newItems.length : 0, addItems, newItemsMap, removeMap, insertAt = begin, indices = me.indices || ((newCount || removeItems) ? me.getIndices() : null), adds = null, removes = removeCount ? [ begin ] : null, newKeys = null, source = me.getSource(), chunk, chunkItems, chunks, i, item, itemIndex, k, key, keys, n, duplicates, sorters; if (source && !source.updating) { if (isRemoveCount) { removeItems = []; for (i = 0; i < removeCount; ++i) { removeItems.push(items[begin + i]); } } if (begin < length) { i = source.indexOf(items[begin]); } else { i = source.length; } source.splice(i, removeItems, newItems); return me; } if (newCount) { addItems = newItems; newKeys = []; newItemsMap = {}; if (autoSort) { sorters = me.getSorters(); if (newCount > 1) { if (!addItems.$cloned) { newItems = addItems = addItems.slice(0); } me.sortData(addItems); } } for (i = 0; i < newCount; ++i) { key = me.getKey(item = newItems[i]); if ((k = newItemsMap[key]) !== undefined) { (duplicates || (duplicates = {}))[k] = 1; } else { itemIndex = indices[key]; if (itemIndex < begin || end <= itemIndex) { (removes || (removes = [])).push(itemIndex); } } newItemsMap[key] = i; newKeys.push(key); } if (duplicates) { keys = newKeys; addItems = []; newKeys = []; addItems.$cloned = true; for (i = 0; i < newCount; ++i) { if (!duplicates[i]) { item = newItems[i]; addItems.push(item); newKeys.push(keys[i]); } } newCount = addItems.length; } adds = { items: addItems, keys: newKeys }; } for (i = removeItems ? removeItems.length : 0; i-- > 0; ) { key = me.getKey(removeItems[i]); if ((itemIndex = indices[key]) !== undefined) { (removes || (removes = [])).push(itemIndex); } } if (!adds && !removes) { return me; } me.beginUpdate(); if (removes) { chunk = null; chunks = []; removeMap = {}; if (removes.length > 1) { removes.sort(Ext.Array.numericSortFn); } for (i = 0 , n = removes.length; i < n; ++i) { key = me.getKey(item = items[itemIndex = removes[i]]); if (!(key in map)) { continue; } delete map[key]; if (!chunk || itemIndex > (chunk.at + chunkItems.length)) { chunks.push(chunk = { at: itemIndex, items: (chunkItems = []), keys: (keys = []), map: removeMap, next: chunk, replacement: adds }); if (adds) { adds.replaced = chunk; } } chunkItems.push(removeMap[key] = item); keys.push(key); if (itemIndex < insertAt) { --insertAt; } if (removeCount > 1 && itemIndex === begin) { --removeCount; removes[i--] = ++begin; } } if (adds) { adds.at = insertAt; } for (k = chunks.length; k-- > 0; ) { chunk = chunks[k]; i = chunk.at; n = chunk.items.length; if (i + n < length) { me.indices = indices = null; } me.length = length -= n; items.splice(i, n); if (indices) { keys = chunk.keys; for (i = 0; i < n; ++i) { delete indices[keys[i]]; } } ++me.generation; me.notify('remove', [ chunk ]); } } if (adds) { if (autoSort && newCount > 1 && length) { me.spliceMerge(addItems, newKeys); } else { if (autoSort) { if (newCount > 1) { insertAt = 0; me.indices = indices = null; } else { insertAt = sorters.findInsertionIndex(adds.items[0], items, me.getSortFn()); } } if (insertAt === length) { items.push.apply(items, addItems); indices = me.indices; if (indices) { for (i = 0; i < newCount; ++i) { indices[newKeys[i]] = insertAt + i; } } } else { me.indices = null; Ext.Array.insert(items, insertAt, addItems); } for (i = 0; i < newCount; ++i) { map[newKeys[i]] = addItems[i]; } me.length += newCount; adds.at = insertAt; adds.atItem = insertAt === 0 ? null : items[insertAt - 1]; ++me.generation; me.notify('add', [ adds ]); } } me.endUpdate(); return me; }, update: function(fn, scope) { var me = this; me.beginUpdate(); try { return fn.call(scope || me, me); } catch (e) { Ext.log.error(this.$className + ': Unhandled Exception: ', e.description || e.message); throw e; } finally { me.endUpdate(); } }, updateKey: function(item, oldKey) { var me = this, map = me.map, indices = me.indices, source = me.getSource(), newKey; if (source && !source.updating) { source.updateKey(item, oldKey); } else if ((newKey = me.getKey(item)) !== oldKey) { if (map[oldKey] === item && !(newKey in map)) { delete map[oldKey]; me.updating++; me.generation++; map[newKey] = item; if (indices) { indices[newKey] = indices[oldKey]; delete indices[oldKey]; } me.notify('updatekey', [ { item: item, newKey: newKey, oldKey: oldKey } ]); me.updating--; } else { if (newKey in map && map[newKey] !== item) { Ext.Error.raise('Duplicate newKey "' + newKey + '" for item with oldKey "' + oldKey + '"'); } if (oldKey in map && map[oldKey] !== item) { Ext.Error.raise('Incorrect oldKey "' + oldKey + '" for item with newKey "' + newKey + '"'); } } } }, findInsertIndex: function(item) { var source = this.getSource(), sourceItems = source.items, i = source.indexOf(item) - 1, sourceItem, index; while (i > -1) { sourceItem = sourceItems[i]; index = this.indexOf(sourceItem); if (index > -1) { return index + 1; } --i; } return 0; }, onCollectionAdd: function(source, details) { var me = this, atItem = details.atItem, items = details.items, requestedIndex = me.requestedIndex, filtered, index, copy, i, item, n; if (!me.sorted) { if (requestedIndex !== undefined) { index = requestedIndex; } else if (atItem) { index = me.indexOf(atItem); if (index === -1) { index = me.findInsertIndex(items[0]); } else { ++index; } } else { index = 0; } } if (me.getAutoFilter() && me.filtered) { for (i = 0 , n = items.length; i < n; ++i) { item = items[i]; if (me.isItemFiltered(item)) { if (!copy) { copy = items.slice(0, i); } if (!filtered) { filtered = []; } filtered.push(item); } else if (copy) { copy.push(item); } } } me.splice((index < 0) ? me.length : index, 0, copy || items); if (filtered) { me.notify('filteradd', [ filtered ]); } }, onCollectionBeforeItemChange: function(source, details) { this.onCollectionUpdateKey = null; }, onCollectionBeginUpdate: function() { this.beginUpdate(); }, onCollectionEndUpdate: function() { this.endUpdate(); }, onCollectionItemChange: function(source, details) { delete this.onCollectionUpdateKey; this.itemChanged(details.item, details.modified, details.oldKey, details.meta); }, onCollectionFilteredItemChange: null, onCollectionRefresh: function(source) { var me = this, map = {}, indices = {}, i, item, items, key, length; items = source.items; items = me.filtered && me.getAutoFilter() ? Ext.Array.filter(items, me.getFilterFn()) : items.slice(0); if (me.sorted) { me.sortData(items); } me.items = items; me.length = length = items.length; me.map = map; me.indices = indices; for (i = 0; i < length; ++i) { key = me.getKey(item = items[i]); map[key] = item; indices[key] = i; } me.notify('refresh'); }, onCollectionRemove: function(source, details) { this.splice(0, details.items); }, onCollectionUpdateKey: function(source, details) { this.updateKey(details.item, details.oldKey); }, _aggregators: { average: function(items, begin, end, property, root) { var n = end - begin; return n && this._aggregators.sum.call(this, items, begin, end, property, root) / n; }, bounds: function(items, begin, end, property, root) { for (var value, max, min, i = begin; i < end; ++i) { value = items[i]; value = (root ? value[root] : value)[property]; if (!(value < max)) { max = value; } if (!(value > min)) { min = value; } } return [ min, max ]; }, count: function(items) { return items.length; }, extremes: function(items, begin, end, property, root) { var most = null, least = null, i, item, max, min, value; for (i = begin; i < end; ++i) { item = items[i]; value = (root ? item[root] : item)[property]; if (!(value < max)) { max = value; most = item; } if (!(value > min)) { min = value; least = item; } } return [ least, most ]; }, max: function(items, begin, end, property, root) { var b = this._aggregators.bounds.call(this, items, begin, end, property, root); return b[1]; }, maxItem: function(items, begin, end, property, root) { var b = this._aggregators.extremes.call(this, items, begin, end, property, root); return b[1]; }, min: function(items, begin, end, property, root) { var b = this._aggregators.bounds.call(this, items, begin, end, property, root); return b[0]; }, minItem: function(items, begin, end, property, root) { var b = this._aggregators.extremes.call(this, items, begin, end, property, root); return b[0]; }, sum: function(items, begin, end, property, root) { for (var value, sum = 0, i = begin; i < end; ++i) { value = items[i]; value = (root ? value[root] : value)[property]; sum += value; } return sum; } }, _eventToMethodMap: { add: 'onCollectionAdd', beforeitemchange: 'onCollectionBeforeItemChange', beginupdate: 'onCollectionBeginUpdate', endupdate: 'onCollectionEndUpdate', itemchange: 'onCollectionItemChange', filtereditemchange: 'onCollectionFilteredItemChange', refresh: 'onCollectionRefresh', remove: 'onCollectionRemove', beforesort: 'beforeCollectionSort', sort: 'onCollectionSort', filter: 'onCollectionFilter', filteradd: 'onCollectionFilterAdd', updatekey: 'onCollectionUpdateKey' }, addObserver: function(observer) { var me = this, observers = me.observers; if (!observers) { me.observers = observers = []; } if (Ext.Array.contains(observers, observer)) { Ext.Error.raise('Observer already added'); } observers.push(observer); if (observers.length > 1) { Ext.Array.sort(observers, me.prioritySortFn); } }, prioritySortFn: function(o1, o2) { var a = o1.observerPriority || 0, b = o2.observerPriority || 0; return a - b; }, applyExtraKeys: function(extraKeys, oldExtraKeys) { var me = this, ret = oldExtraKeys || {}, config, name, value; for (name in extraKeys) { value = extraKeys[name]; if (!value.isCollectionKey) { config = { collection: me }; if (Ext.isString(value)) { config.property = value; } else { config = Ext.apply(config, value); } value = new Ext.util.CollectionKey(config); } else { value.setCollection(me); } ret[name] = me[name] = value; value.name = name; } return ret; }, applyGrouper: function(grouper) { if (grouper) { grouper = this.getSorters().decodeSorter(grouper, 'Ext.util.Grouper'); } return grouper; }, decodeItems: function(args, index) { var me = this, ret = (index === undefined) ? args : args[index], cloned, decoder, i; if (!ret || !ret.$cloned) { cloned = args.length > index + 1 || !Ext.isIterable(ret); if (cloned) { ret = Ext.Array.slice(args, index); if (ret.length === 1 && ret[0] === undefined) { ret.length = 0; } } decoder = me.getDecoder(); if (decoder) { if (!cloned) { ret = ret.slice(0); cloned = true; } for (i = ret.length; i-- > 0; ) { if ((ret[i] = decoder.call(me, ret[i])) === false) { ret.splice(i, 1); } } } if (cloned) { ret.$cloned = true; } } return ret; }, getIndices: function() { var me = this, indices = me.indices, items = me.items, n = items.length, i, key; if (!indices) { me.indices = indices = {}; ++me.indexRebuilds; for (i = 0; i < n; ++i) { key = me.getKey(items[i]); indices[key] = i; } } return indices; }, notify: function(eventName, args) { var me = this, observers = me.observers, methodName = me._eventToMethodMap[eventName], added = 0, index, length, method, observer; args = args || []; if (observers && methodName) { for (index = 0 , length = observers.length; index < length; ++index) { method = (observer = observers[index])[methodName]; if (method) { if (!added++) { args.unshift(me); } method.apply(observer, args); } } } if (!me.hasListeners) { return; } if (me.hasListeners[eventName]) { if (!added) { args.unshift(me); } me.fireEventArgs(eventName, args); } }, getFilterFn: function() { return this.getFilters().getFilterFn(); }, getFilters: function(autoCreate) { var ret = this._filters; if (!ret && autoCreate !== false) { ret = new Ext.util.FilterCollection(); this.setFilters(ret); } return ret; }, isItemFiltered: function(item) { return !this.getFilters().filterFn(item); }, onFilterChange: function(filters) { var me = this, source = me.getSource(), extraKeys, newKeys, key; if (!source) { extraKeys = me.getExtraKeys(); if (extraKeys) { newKeys = {}; for (key in extraKeys) { newKeys[key] = extraKeys[key].clone(me); } } source = new Ext.util.Collection({ keyFn: me.getKey, extraKeys: newKeys, rootProperty: me.getRootProperty() }); if (me.length) { source.add(me.items); } me.setSource(source); me.autoSource = source; } else if (source.length || me.length) { me.onCollectionRefresh(source); } me.notify('filter'); }, applyFilters: function(filters, collection) { if (filters == null || (filters && filters.isFilterCollection)) { return filters; } if (filters) { if (!collection) { collection = this.getFilters(); } collection.splice(0, collection.length, filters); } return collection; }, updateFilters: function(newFilters, oldFilters) { var me = this; if (oldFilters) { oldFilters.un('endupdate', 'onEndUpdateFilters', me); } if (newFilters) { newFilters.on({ endupdate: 'onEndUpdateFilters', scope: me, priority: me.$endUpdatePriority }); newFilters.$filterable = me; } me.onEndUpdateFilters(newFilters); }, onEndUpdateFilters: function(filters) { var me = this, was = me.filtered, is = !!filters && (filters.length > 0); if (was || is) { me.filtered = is; me.onFilterChange(filters); } }, getSortFn: function() { return this._sortFn || this.createSortFn(); }, getSorters: function(autoCreate) { var ret = this._sorters; if (!ret && autoCreate !== false) { ret = new Ext.util.SorterCollection(); this.setSorters(ret); } return ret; }, onSortChange: function() { if (this.sorted) { this.sortItems(); } }, sort: function(property, direction, mode) { var sorters = this.getSorters(); sorters.addSort.apply(sorters, arguments); return this; }, sortData: function(data) { Ext.Array.sort(data, this.getSortFn()); return data; }, sortItems: function(sortFn) { var me = this; if (me.sorted) { if (sortFn) { Ext.Error.raise('Collections with sorters cannot resorted'); } sortFn = me.getSortFn(); } me.indices = null; me.notify('beforesort', [ me.getSorters(false) ]); if (me.length) { Ext.Array.sort(me.items, sortFn); } me.notify('sort'); }, sortBy: function(sortFn) { return this.sortItems(sortFn); }, findInsertionIndex: function(item, items, comparatorFn) { if (!items) { items = this.items; } if (!comparatorFn) { comparatorFn = this.getSortFn(); } return Ext.Array.binarySearch(items, item, comparatorFn); }, applySorters: function(sorters, collection) { if (sorters == null || (sorters && sorters.isSorterCollection)) { return sorters; } if (sorters) { if (!collection) { collection = this.getSorters(); } collection.splice(0, collection.length, sorters); } return collection; }, createSortFn: function() { var me = this, grouper = me.getGrouper(), sorters = me.getSorters(false), sorterFn = sorters ? sorters.getSortFn() : null; if (!grouper) { return sorterFn; } return function(lhs, rhs) { var ret = grouper.sort(lhs, rhs); if (!ret && sorterFn) { ret = sorterFn(lhs, rhs); } return ret; }; }, updateGrouper: function(grouper) { var me = this, groups = me.getGroups(), sorters = me.getSorters(), populate; me.onSorterChange(); me.grouped = !!grouper; if (grouper) { if (!groups) { groups = new Ext.util.GroupCollection({ itemRoot: me.getRootProperty() }); groups.$groupable = me; me.setGroups(groups); } groups.setGrouper(grouper); populate = true; } else { if (groups) { me.removeObserver(groups); groups.destroy(); } me.setGroups(null); } if (!sorters.updating) { me.onEndUpdateSorters(sorters); } if (populate) { groups.onCollectionRefresh(me); } }, updateSorters: function(newSorters, oldSorters) { var me = this; if (oldSorters) { oldSorters.un('endupdate', 'onEndUpdateSorters', me); } if (newSorters) { newSorters.on({ endupdate: 'onEndUpdateSorters', scope: me, priority: me.$endUpdatePriority }); newSorters.$sortable = me; } me.onSorterChange(); me.onEndUpdateSorters(newSorters); }, onSorterChange: function() { this._sortFn = null; }, onEndUpdateSorters: function(sorters) { var me = this, was = me.sorted, is = (me.grouped && me.getAutoGroup()) || (sorters && sorters.length > 0); if (was || is) { me.sorted = !!is; me.onSortChange(sorters); } }, removeObserver: function(observer) { var observers = this.observers; if (observers) { Ext.Array.remove(observers, observer); } }, spliceMerge: function(newItems, newKeys) { var me = this, map = me.map, newLength = newItems.length, oldIndex = 0, oldItems = me.items, oldLength = oldItems.length, adds = [], count = 0, items = [], sortFn = me.getSortFn(), addItems, end, i, newItem, oldItem, newIndex; me.items = items; for (newIndex = 0; newIndex < newLength; newIndex = end) { newItem = newItems[newIndex]; for (; oldIndex < oldLength; ++oldIndex) { if (sortFn(newItem, oldItem = oldItems[oldIndex]) < 0) { break; } items.push(oldItem); } if (oldIndex === oldLength) { adds[count++] = { at: items.length, itemAt: items[items.length - 1], items: (addItems = []) }; if (count > 1) { adds[count - 2].next = adds[count - 1]; } for (; newIndex < newLength; ++newIndex) { addItems.push(newItem = newItems[newIndex]); items.push(newItem); } break; } adds[count++] = { at: items.length, itemAt: items[items.length - 1], items: (addItems = [ newItem ]) }; if (count > 1) { adds[count - 2].next = adds[count - 1]; } items.push(newItem); for (end = newIndex + 1; end < newLength; ++end) { if (sortFn(newItem = newItems[end], oldItem) >= 0) { break; } items.push(newItem); addItems.push(newItem); } } for (; oldIndex < oldLength; ++oldIndex) { items.push(oldItems[oldIndex]); } for (i = 0; i < newLength; ++i) { map[newKeys[i]] = newItems[i]; } me.length = items.length; ++me.generation; me.indices = null; for (i = 0; i < count; ++i) { me.notify('add', [ adds[i] ]); } }, getGroups: function() { return this.callParent() || null; }, updateAutoGroup: function(autoGroup) { var groups = this.getGroups(); if (groups) { groups.setAutoGroup(autoGroup); } this.onEndUpdateSorters(this._sorters); }, updateGroups: function(newGroups, oldGroups) { if (oldGroups) { this.removeObserver(oldGroups); } if (newGroups) { this.addObserver(newGroups); } }, updateSource: function(newSource, oldSource) { var auto = this.autoSource; if (oldSource) { oldSource.removeObserver(this); if (oldSource === auto) { auto.destroy(); this.autoSource = null; } } if (newSource) { newSource.addObserver(this); if (newSource.length || this.length) { this.onCollectionRefresh(newSource); } } } }, function() { var prototype = this.prototype; prototype.removeAtKey = prototype.removeByKey; prototype.decodeRemoveItems = prototype.decodeItems; Ext.Object.each(prototype._aggregators, function(name) { prototype[name] = function(property, begin, end) { return this.aggregate(property, name, begin, end); }; prototype[name + 'ByGroup'] = function(property) { return this.aggregateByGroup(property, name); }; }); }); Ext.define('Ext.util.ObjectTemplate', { requires: [ 'Ext.XTemplate' ], isObjectTemplate: true, excludeProperties: {}, valueRe: /^[{][a-z\.]+[}]$/i, statics: { create: function(template, options) { if (!Ext.isObject(template)) { Ext.Error.raise('The template is not an Object'); } return template.isObjectTemplate ? template : new Ext.util.ObjectTemplate(template, options); } }, constructor: function(template, options) { Ext.apply(this, options); this.template = template; }, apply: function(context) { var me = this; delete me.apply; me.apply = me.compile(me.template); return me.apply(context); }, privates: { compile: function(template) { var me = this, exclude = me.excludeProperties, compiled, i, len, fn; if (Ext.isString(template)) { if (template.indexOf('{') < 0) { fn = function() { return template; }; } else if (me.valueRe.test(template)) { template = template.substring(1, template.length - 1).split('.'); fn = function(context) { for (var v = context, i = 0; v && i < template.length; ++i) { v = v[template[i]]; } return v; }; } else { template = new Ext.XTemplate(template); fn = function(context) { return template.apply(context); }; } } else if (!template || Ext.isPrimitive(template) || Ext.isFunction(template)) { fn = function() { return template; }; } else if (template instanceof Array) { compiled = []; for (i = 0 , len = template.length; i < len; ++i) { compiled[i] = me.compile(template[i]); } fn = function(context) { var ret = [], i; for (i = 0; i < len; ++i) { ret[i] = compiled[i](context); } return ret; }; } else { compiled = {}; for (i in template) { if (!exclude[i]) { compiled[i] = me.compile(template[i]); } } fn = function(context) { var ret = {}, i, v; for (i in template) { v = exclude[i] ? template[i] : compiled[i](context); if (v !== undefined) { ret[i] = v; } } return ret; }; } return fn; } } }); Ext.define('Ext.data.schema.Role', { isRole: true, left: true, owner: false, side: 'left', isMany: false, defaultReaderType: 'json', _internalReadOptions: { recordsOnly: true, asRoot: true }, constructor: function(association, config) { var me = this, extra = config.extra; Ext.apply(me, config); if (extra) { delete extra.type; Ext.apply(me, extra); delete me.extra; } me.association = association; if (association.owner === me.side) { association.owner = me; me.owner = true; } }, processUpdate: function() { Ext.Error.raise('Only the "many" for an association may be processed. "' + this.role + '" is not valid.'); }, processLoad: function(store, associatedEntity, records, session) { return records; }, checkMembership: Ext.emptyFn, adoptAssociated: function(record, session) { var other = this.getAssociatedItem(record); if (other) { session.adopt(other); } }, createAssociationStore: function(session, from, records, isComplete) { var me = this, association = me.association, foreignKeyName = association.getFieldName(), isMany = association.isManyToMany, storeConfig = me.storeConfig, id = from.getId(), config = { model: me.cls, role: me, session: session, associatedEntity: from, disableMetaChangeEvent: true, pageSize: null, remoteFilter: true, trackRemoved: !session }, store; if (isMany) { config.filters = [ { property: me.inverse.field, value: id, exactMatch: true } ]; } else if (foreignKeyName) { config.filters = [ { property: foreignKeyName, value: id, exactMatch: true } ]; config.foreignKeyName = foreignKeyName; } if (storeConfig) { Ext.apply(config, storeConfig); } store = Ext.Factory.store(config); me.onStoreCreate(store, session, id); if (foreignKeyName || (isMany && session)) { store.on({ scope: me, add: 'onAddToMany', remove: 'onRemoveFromMany', clear: 'onRemoveFromMany' }); } if (records) { store.loadData(records); store.complete = !!isComplete; } return store; }, onStoreCreate: Ext.emptyFn, getAssociatedStore: function(inverseRecord, options, scope, records, isComplete) { var me = this, storeName = me.getStoreName(), store = inverseRecord[storeName], load = options && options.reload, source = inverseRecord.$source, session = inverseRecord.session, args, i, len, raw, rec, sourceStore; if (!store) { if (!records && source) { source = source[storeName]; if (source && !source.isLoading()) { sourceStore = source; records = []; raw = source.getData().items; for (i = 0 , len = raw.length; i < len; ++i) { rec = raw[i]; records.push(session.getRecord(rec.self, rec.id)); } isComplete = true; } } store = me.createAssociationStore(session, inverseRecord, records, isComplete); store.$source = sourceStore; if (!records && (me.autoLoad || options)) { load = true; } inverseRecord[storeName] = store; } if (options) { if (load || store.isLoading()) { store.on('load', function(store, records, success, operation) { args = [ store, operation ]; scope = scope || options.scope || inverseRecord; if (success) { Ext.callback(options.success, scope, args); } else { Ext.callback(options.failure, scope, args); } args.push(success); Ext.callback(options, scope, args); Ext.callback(options.callback, scope, args); }, null, { single: true }); } else { args = [ store, null ]; scope = scope || options.scope || inverseRecord; Ext.callback(options.success, scope, args); args.push(true); Ext.callback(options, scope, args); Ext.callback(options.callback, scope, args); } } if (load && !store.isLoading()) { store.load(); } return store; }, getAssociatedItem: function(rec) { var key = this.isMany ? this.getStoreName() : this.getInstanceName(); return rec[key] || null; }, onDrop: Ext.emptyFn, getReaderRoot: function() { var me = this; return me.associationKey || (me.associationKey = me.association.schema.getNamer().readerRoot(me.role)); }, getReader: function() { var me = this, reader = me.reader, Model = me.cls, useSimpleAccessors = !me.associationKey, root = this.getReaderRoot(); if (reader && !reader.isReader) { if (Ext.isString(reader)) { reader = { type: reader }; } Ext.applyIf(reader, { model: Model, rootProperty: root, useSimpleAccessors: useSimpleAccessors, type: me.defaultReaderType }); reader = me.reader = Ext.createByAlias('reader.' + reader.type, reader); } return reader; }, getInstanceName: function() { var me = this; return me.instanceName || (me.instanceName = me.association.schema.getNamer().instanceName(me.role)); }, getOldInstanceName: function() { return this.oldInstanceName || (this.oldInstanceName = '$old' + this.getInstanceName()); }, getStoreName: function() { var me = this; return me.storeName || (me.storeName = me.association.schema.getNamer().storeName(me.role)); }, constructReader: function(fromReader) { var me = this, reader = me.getReader(), Model = me.cls, useSimpleAccessors = !me.associationKey, root = me.getReaderRoot(), proxyReader, proxy; if (!reader) { proxy = Model.getProxy(); if (proxy) { proxyReader = proxy.getReader(); reader = new proxyReader.self(); reader.copyFrom(proxyReader); reader.setRootProperty(root); } else { reader = new fromReader.self({ model: Model, useSimpleAccessors: useSimpleAccessors, rootProperty: root }); } me.reader = reader; } return reader; }, read: function(record, data, fromReader, readOptions) { var reader = this.constructReader(fromReader), root = reader.getRoot(data); if (root) { return reader.readRecords(root, readOptions, this._internalReadOptions); } }, getCallbackOptions: function(options, scope, defaultScope) { if (typeof options === 'function') { options = { callback: options, scope: scope || defaultScope }; } else if (options) { options = Ext.apply({}, options); options.scope = scope || options.scope || defaultScope; } return options; }, doGetFK: function(leftRecord, options, scope) { var me = this, cls = me.cls, foreignKey = me.association.getFieldName(), instanceName = me.getInstanceName(), rightRecord = leftRecord[instanceName], reload = options && options.reload, done = rightRecord !== undefined && !reload, session = leftRecord.session, foreignKeyId, args; if (!done) { if (session) { foreignKeyId = leftRecord.get(foreignKey); if (foreignKeyId || foreignKeyId === 0) { done = session.peekRecord(cls, foreignKeyId, true) && !reload; rightRecord = session.getRecord(cls, foreignKeyId, false); } else { done = true; leftRecord[instanceName] = rightRecord = null; } } else if (foreignKey) { foreignKeyId = leftRecord.get(foreignKey); if (!foreignKeyId && foreignKeyId !== 0) { done = true; leftRecord[instanceName] = rightRecord = null; } else { if (!rightRecord) { rightRecord = cls.createWithId(foreignKeyId); } } } else { done = true; } } else if (rightRecord) { done = !rightRecord.isLoading(); } if (done) { if (options) { args = [ rightRecord, null ]; scope = scope || options.scope || leftRecord; Ext.callback(options.success, scope, args); args.push(true); Ext.callback(options, scope, args); Ext.callback(options.callback, scope, args); } } else { leftRecord[instanceName] = rightRecord; options = me.getCallbackOptions(options, scope, leftRecord); rightRecord.load(options); } return rightRecord; }, doSetFK: function(leftRecord, rightRecord, options, scope) { var me = this, foreignKey = me.association.getFieldName(), instanceName = me.getInstanceName(), current = leftRecord[instanceName], inverse = me.inverse, inverseSetter = inverse.setterName, session = leftRecord.session, modified, oldInstanceName; if (rightRecord && rightRecord.isEntity) { if (current !== rightRecord) { oldInstanceName = me.getOldInstanceName(); leftRecord[oldInstanceName] = current; leftRecord[instanceName] = rightRecord; if (current && current.isEntity) { current[inverse.getInstanceName()] = undefined; } if (foreignKey) { leftRecord.set(foreignKey, rightRecord.getId()); } delete leftRecord[oldInstanceName]; if (inverseSetter) { rightRecord[inverseSetter](leftRecord); } } } else { if (!foreignKey) { Ext.Error.raise('No foreignKey specified for "' + me.association.left.role + '" by ' + leftRecord.$className); } modified = (leftRecord.changingKey && !inverse.isMany) || leftRecord.set(foreignKey, rightRecord); if (modified && current && current.isEntity && !current.isEqual(current.getId(), rightRecord)) { leftRecord[instanceName] = undefined; if (!inverse.isMany) { current[inverse.getInstanceName()] = undefined; } } } if (options) { if (Ext.isFunction(options)) { options = { callback: options, scope: scope || leftRecord }; } return leftRecord.save(options); } } }); Ext.define('Ext.data.schema.Association', { requires: [ 'Ext.data.schema.Role' ], isOneToOne: false, isManyToOne: false, isManyToMany: false, owner: null, field: null, constructor: function(config) { var me = this, left, right; Ext.apply(me, config); me.left = left = new me.Left(me, me.left); me.right = right = new me.Right(me, me.right); left.inverse = right; right.inverse = left; }, hasField: function() { return !!this.field; }, getFieldName: function() { var field = this.field; return field ? field.name : ''; } }); Ext.define('Ext.data.schema.OneToOne', { extend: 'Ext.data.schema.Association', isOneToOne: true, isToOne: true, kind: 'one-to-one', Left: Ext.define(null, { extend: 'Ext.data.schema.Role', onDrop: function(rightRecord, session) { var leftRecord = this.getAssociatedItem(rightRecord); rightRecord[this.getInstanceName()] = null; if (leftRecord) { leftRecord[this.inverse.getInstanceName()] = null; } }, createGetter: function() { var me = this; return function() { return me.doGet(this); }; }, createSetter: function() { var me = this; return function(value) { return me.doSet(this, value); }; }, doGet: function(rightRecord) { var instanceName = this.getInstanceName(), ret = rightRecord[instanceName], session = rightRecord.session; if (!ret && session) {} return ret || null; }, doSet: function(rightRecord, leftRecord) { var instanceName = this.getInstanceName(), ret = rightRecord[instanceName], inverseSetter = this.inverse.setterName; if (ret !== leftRecord) { rightRecord[instanceName] = leftRecord; if (inverseSetter) { leftRecord[inverseSetter](rightRecord); } } return ret; }, read: function(rightRecord, node, fromReader, readOptions) { var me = this, leftRecords = me.callParent([ rightRecord, node, fromReader, readOptions ]), leftRecord; if (leftRecords) { leftRecord = leftRecords[0]; if (leftRecord) { leftRecord[me.inverse.getInstanceName()] = rightRecord; rightRecord[me.getInstanceName()] = leftRecord; delete rightRecord.data[me.role]; } } } }), Right: Ext.define(null, { extend: 'Ext.data.schema.Role', left: false, side: 'right', createGetter: function() { var me = this; return function(options, scope) { return me.doGetFK(this, options, scope); }; }, createSetter: function() { var me = this; return function(value, options, scope) { return me.doSetFK(this, value, options, scope); }; }, onDrop: function(leftRecord, session) { var me = this, field = me.association.field, rightRecord = me.getAssociatedItem(leftRecord), id; if (me.inverse.owner) { if (session) { id = leftRecord.get(field.name); if (id || id === 0) { rightRecord = session.getEntry(me.cls, id).record; if (rightRecord) { rightRecord.drop(); } } } else { if (rightRecord) { rightRecord.drop(); } } } if (field) { leftRecord.set(field.name, null); } leftRecord[me.getInstanceName()] = null; if (rightRecord) { rightRecord[me.inverse.getInstanceName()] = null; } }, onValueChange: function(leftRecord, session, newValue) { var me = this, rightRecord = leftRecord[me.getOldInstanceName()] || me.getAssociatedItem(leftRecord), hasNewValue = newValue || newValue === 0, instanceName = me.getInstanceName(), cls = me.cls; leftRecord.changingKey = true; me.doSetFK(leftRecord, newValue); if (!hasNewValue) { leftRecord[instanceName] = null; } else if (session && cls) { leftRecord[instanceName] = session.peekRecord(cls, newValue) || undefined; } if (me.inverse.owner && rightRecord) { me.association.schema.queueKeyCheck(rightRecord, me); } leftRecord.changingKey = false; }, checkKeyForDrop: function(rightRecord) { var leftRecord = this.inverse.getAssociatedItem(rightRecord); if (!leftRecord) { rightRecord.drop(); } }, read: function(leftRecord, node, fromReader, readOptions) { var me = this, rightRecords = me.callParent([ leftRecord, node, fromReader, readOptions ]), rightRecord, field, fieldName, session, refs, id, oldId, setKey, data; if (rightRecords) { rightRecord = rightRecords[0]; field = me.association.field; fieldName = field.name; session = leftRecord.session; data = leftRecord.data; if (rightRecord) { if (session) { refs = session.getRefs(rightRecord, this.inverse, true); setKey = (refs && refs[leftRecord.id]) || (data[fieldName] === undefined); } else { setKey = true; } if (setKey) { if (field) { oldId = data[fieldName]; id = rightRecord.id; if (oldId !== id) { data[fieldName] = id; if (session) { session.updateReference(leftRecord, field, id, oldId); } } } rightRecord[me.inverse.getInstanceName()] = leftRecord; leftRecord[me.getInstanceName()] = rightRecord; } delete data[me.role]; } } } }) }); Ext.define('Ext.data.schema.ManyToOne', { extend: 'Ext.data.schema.Association', isManyToOne: true, isToOne: true, kind: 'many-to-one', Left: Ext.define(null, { extend: 'Ext.data.schema.Role', isMany: true, onDrop: function(rightRecord, session) { var me = this, store = me.getAssociatedItem(rightRecord), leftRecords, len, i, refs, id; if (store) { leftRecords = store.removeAll(); if (leftRecords && me.inverse.owner) { for (i = 0 , len = leftRecords.length; i < len; ++i) { leftRecords[i].drop(); } } store.destroy(); rightRecord[me.getStoreName()] = null; } else if (session) { leftRecords = session.getRefs(rightRecord, me); if (leftRecords) { for (id in leftRecords) { leftRecords[id].drop(); } } } }, processUpdate: function(session, associationData) { var me = this, entityType = me.inverse.cls, items = associationData.R, id, rightRecord, store, leftRecords; if (items) { for (id in items) { rightRecord = session.peekRecord(entityType, id); if (rightRecord) { leftRecords = session.getEntityList(me.cls, items[id]); store = me.getAssociatedItem(rightRecord); if (store) { store.loadData(leftRecords); store.complete = true; } else { rightRecord[me.getterName](null, null, leftRecords); } } else { session.onInvalidAssociationEntity(entityType, id); } } } }, findRecords: function(session, rightRecord, leftRecords, allowInfer) { var ret = leftRecords, refs = session.getRefs(rightRecord, this, true), field = this.association.field, fieldName = field.name, leftRecord, id, i, len, seen; if (!rightRecord.phantom) { ret = []; if (refs || allowInfer) { if (leftRecords) { seen = {}; for (i = 0 , len = leftRecords.length; i < len; ++i) { leftRecord = leftRecords[i]; id = leftRecord.id; if (refs && refs[id]) { ret.push(leftRecord); } else if (allowInfer && leftRecord.data[fieldName] === undefined) { ret.push(leftRecord); leftRecord.data[fieldName] = rightRecord.id; session.updateReference(leftRecord, field, rightRecord.id, undefined); } seen[id] = true; } } if (refs) { for (id in refs) { if (!seen || !seen[id]) { ret.push(refs[id]); } } } } } return ret; }, processLoad: function(store, rightRecord, leftRecords, session) { var ret = leftRecords; if (session) { ret = this.findRecords(session, rightRecord, leftRecords); } this.onLoadMany(rightRecord, ret, session); return ret; }, adoptAssociated: function(rightRecord, session) { var store = this.getAssociatedItem(rightRecord), leftRecords, i, len; if (store) { store.setSession(session); leftRecords = store.getData().items; for (i = 0 , len = leftRecords.length; i < len; ++i) { session.adopt(leftRecords[i]); } } }, createGetter: function() { var me = this; return function(options, scope, leftRecords) { var session = this.session, hadRecords = !!leftRecords; if (session) { leftRecords = me.findRecords(session, this, leftRecords, true); if (!hadRecords && (!leftRecords || !leftRecords.length)) { leftRecords = null; } } return me.getAssociatedStore(this, options, scope, leftRecords, hadRecords); }; }, createSetter: null, onAddToMany: function(store, leftRecords) { this.syncFK(leftRecords, store.getAssociatedEntity(), false); }, onLoadMany: function(rightRecord, leftRecords, session) { var instanceName = this.inverse.getInstanceName(), id = rightRecord.getId(), field = this.association.field, i, len, leftRecord, oldId, data, name; if (field) { for (i = 0 , len = leftRecords.length; i < len; ++i) { leftRecord = leftRecords[i]; leftRecord[instanceName] = rightRecord; if (field) { name = field.name; data = leftRecord.data; oldId = data[name]; if (oldId !== id) { data[name] = id; if (session) { session.updateReference(leftRecord, field, id, oldId); } } } } } }, onRemoveFromMany: function(store, leftRecords) { this.syncFK(leftRecords, store.getAssociatedEntity(), true); }, read: function(rightRecord, node, fromReader, readOptions) { var me = this, instanceName = me.inverse.getInstanceName(), leftRecords = me.callParent([ rightRecord, node, fromReader, readOptions ]), store, len, i; if (leftRecords) { store = rightRecord[me.getterName](null, null, leftRecords); delete rightRecord.data[me.role]; leftRecords = store.getData().items; for (i = 0 , len = leftRecords.length; i < len; ++i) { leftRecords[i][instanceName] = rightRecord; } } }, syncFK: function(leftRecords, rightRecord, clearing) { var foreignKeyName = this.association.getFieldName(), inverse = this.inverse, setter = inverse.setterName, instanceName = inverse.getInstanceName(), i = leftRecords.length, id = rightRecord.getId(), different, leftRecord, val; while (i-- > 0) { leftRecord = leftRecords[i]; different = !leftRecord.isEqual(id, leftRecord.get(foreignKeyName)); val = clearing ? null : rightRecord; if (different !== clearing) { leftRecord.changingKey = true; leftRecord[setter](val); leftRecord.changingKey = false; } else { leftRecord[instanceName] = val; } } } }), Right: Ext.define(null, { extend: 'Ext.data.schema.Role', left: false, side: 'right', onDrop: function(leftRecord, session) { var field = this.association.field; if (field) { leftRecord.set(field.name, null); } leftRecord[this.getInstanceName()] = null; }, createGetter: function() { var me = this; return function(options, scope) { return me.doGetFK(this, options, scope); }; }, createSetter: function() { var me = this; return function(rightRecord, options, scope) { return me.doSetFK(this, rightRecord, options, scope); }; }, checkMembership: function(session, leftRecord) { var field = this.association.field, store; store = this.getSessionStore(session, leftRecord.get(field.name)); if (store && !store.contains(leftRecord)) { store.add(leftRecord); } }, onValueChange: function(leftRecord, session, newValue, oldValue) { var me = this, instanceName = me.getInstanceName(), cls = me.cls, hasNewValue, joined, store, i, len, associated, rightRecord; if (!leftRecord.changingKey) { hasNewValue = newValue || newValue === 0; if (!hasNewValue) { leftRecord[instanceName] = null; } if (session) { store = me.getSessionStore(session, oldValue); if (store) { store.remove(leftRecord); } if (hasNewValue) { store = me.getSessionStore(session, newValue); if (store && !store.isLoading()) { store.add(leftRecord); } if (cls) { rightRecord = session.peekRecord(cls, newValue); } leftRecord[instanceName] = rightRecord || undefined; } } else { joined = leftRecord.joined; if (joined) { for (i = 0 , len = joined.length; i < len; ++i) { store = joined[i]; if (store.isStore) { associated = store.getAssociatedEntity(); if (associated && associated.self === me.cls && associated.getId() === oldValue) { store.remove(leftRecord); } } } } } } if (me.owner && newValue === null) { me.association.schema.queueKeyCheck(leftRecord, me); } }, checkKeyForDrop: function(leftRecord) { var field = this.association.field; if (leftRecord.get(field.name) === null) { leftRecord.drop(); } }, getSessionStore: function(session, value) { var cls = this.cls, rec; if (cls) { rec = session.peekRecord(cls, value); if (rec) { return this.inverse.getAssociatedItem(rec); } } }, read: function(leftRecord, node, fromReader, readOptions) { var rightRecords = this.callParent([ leftRecord, node, fromReader, readOptions ]), rightRecord; if (rightRecords) { rightRecord = rightRecords[0]; if (rightRecord) { leftRecord[this.getInstanceName()] = rightRecord; delete leftRecord.data[this.role]; } } } }) }); Ext.define('Ext.data.schema.ManyToMany', { extend: 'Ext.data.schema.Association', isManyToMany: true, isToMany: true, kind: 'many-to-many', Left: Ext.define(null, { extend: 'Ext.data.schema.Role', isMany: true, digitRe: /^\d+$/, findRecords: function(session, rightRecord, leftRecords) { var slice = session.getMatrixSlice(this.inverse, rightRecord.id), members = slice.members, ret = [], cls = this.cls, seen, i, len, id, member, leftRecord; if (leftRecords) { seen = {}; for (i = 0 , len = leftRecords.length; i < len; ++i) { leftRecord = leftRecords[i]; id = leftRecord.id; member = members[id]; if (!(member && member[2] === -1)) { ret.push(leftRecord); } seen[id] = true; } } for (id in members) { member = members[id]; if (!seen || !seen[id] && (member && member[2] !== -1)) { leftRecord = session.peekRecord(cls, id); if (leftRecord) { ret.push(leftRecord); } } } return ret; }, processLoad: function(store, rightRecord, leftRecords, session) { var ret = leftRecords; if (session) { ret = this.findRecords(session, rightRecord, leftRecords); this.onAddToMany(store, ret, true); } return ret; }, processUpdate: function(session, associationData) { var me = this, entityType = me.inverse.cls, items = associationData.R, id, rightRecord, store, leftRecords; if (items) { for (id in items) { rightRecord = session.peekRecord(entityType, id); if (rightRecord) { leftRecords = session.getEntityList(me.cls, items[id]); store = me.getAssociatedItem(rightRecord); if (store) { store.loadData(leftRecords); store.complete = true; } else { rightRecord[me.getterName](null, null, leftRecords); } } else { session.onInvalidAssociationEntity(entityType, id); } } } me.processMatrixBlock(session, associationData.C, 1); me.processMatrixBlock(session, associationData.D, -1); }, checkMembership: function(session, rightRecord) { var matrix = session.getMatrix(this.association, true), side, entityType, inverse, slice, slices, id, members, member, leftRecord, store; if (!matrix) { return; } side = this.left ? matrix.right : matrix.left; entityType = side.inverse.role.cls; inverse = this.inverse; slices = side.slices; if (slices) { slice = slices[rightRecord.id]; if (slice) { members = slice.members; for (id in members) { member = members[id]; if (member[2] !== -1) { leftRecord = session.peekRecord(entityType, id); if (leftRecord) { store = inverse.getAssociatedItem(leftRecord); if (store) { store.matrixUpdate = 1; store.add(rightRecord); store.matrixUpdate = 0; } } } } } } }, onStoreCreate: function(store, session, id) { var me = this, matrix; if (session) { matrix = session.getMatrixSlice(me.inverse, id); matrix.attach(store); matrix.notify = me.onMatrixUpdate; matrix.scope = me; } }, processMatrixBlock: function(session, leftKeys, state) { var inverse = this.inverse, digitRe = this.digitRe, slice, id; if (leftKeys) { for (id in leftKeys) { if (digitRe.test(id)) { id = parseInt(id, 10); } slice = session.getMatrixSlice(inverse, id); slice.update(leftKeys[id], state); } } }, createGetter: function() { var me = this; return function(options, scope, leftRecords) { var session = this.session, hadRecords; if (session) { hadRecords = !!leftRecords; leftRecords = me.findRecords(session, this, leftRecords); if (!hadRecords && !leftRecords.length) { leftRecords = null; } } return me.getAssociatedStore(this, options, scope, leftRecords, hadRecords); }; }, onAddToMany: function(store, leftRecords, load) { if (!store.matrixUpdate) { store.matrixUpdate = 1; store.matrix.update(leftRecords, load === true ? 0 : 1); store.matrixUpdate = 0; } }, onRemoveFromMany: function(store, records) { if (!store.matrixUpdate) { store.matrixUpdate = 1; store.matrix.update(records, -1); store.matrixUpdate = 0; } }, read: function(rightRecord, node, fromReader, readOptions) { var me = this, leftRecords = me.callParent([ rightRecord, node, fromReader, readOptions ]); if (leftRecords) { rightRecord[me.getterName](null, null, leftRecords); delete rightRecord.data[me.role]; } }, onMatrixUpdate: function(matrixSlice, id, state) { var store = matrixSlice.store, index, leftRecord, entry; if (store && !store.loading && !store.matrixUpdate) { store.matrixUpdate = 1; index = store.indexOfId(id); if (state < 0) { if (index >= 0) { store.remove([ index ]); } } else if (index < 0) { entry = store.getSession().getEntry(this.type, id); leftRecord = entry && entry.record; if (leftRecord) { store.add(leftRecord); } } store.matrixUpdate = 0; } }, adoptAssociated: function(record, session) { var store = this.getAssociatedItem(record), records, i, len; if (store) { store.setSession(session); this.onStoreCreate(store, session, record.getId()); records = store.getData().items; for (i = 0 , len = records.length; i < len; ++i) { session.adopt(records[i]); } } } }, function() { var Left = this; Ext.ClassManager.onCreated(function() { Ext.data.schema.ManyToMany.prototype.Right = Ext.define(null, { extend: Left, left: false, side: 'right' }); }, null, 'Ext.data.schema.ManyToMany'); }) }); Ext.define('Ext.util.Inflector', { singleton: true, 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" ], [ (/^(p)erson$/i), "$1eople" ], [ (/^(m)an$/i), "$1en" ], [ (/(.*)(child)(ren)?$/i), "$1$2ren" ], [ (/s$/i), "s" ], [ (/$/), "s" ] ], singulars: [ [ (/(address)$/i), "$1" ], [ (/(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" ], [ (/(p)eople$/i), "$1erson" ], [ (/s$/i), "" ] ], uncountable: [ "sheep", "fish", "series", "species", "money", "rice", "information", "equipment", "grass", "mud", "offspring", "deer", "means" ], singular: function(matcher, replacer) { this.singulars.unshift([ matcher, replacer ]); }, plural: function(matcher, replacer) { this.plurals.unshift([ matcher, replacer ]); }, clearSingulars: function() { this.singulars = []; }, clearPlurals: function() { this.plurals = []; }, isTransnumeral: function(word) { return Ext.Array.indexOf(this.uncountable, word) != -1; }, pluralize: function(word) { if (this.isTransnumeral(word)) { return word; } var plurals = this.plurals, length = plurals.length, tuple, regex, i; for (i = 0; i < length; i++) { tuple = plurals[i]; regex = tuple[0]; if (regex == word || (regex.test && regex.test(word))) { return word.replace(regex, tuple[1]); } } return word; }, singularize: function(word) { if (this.isTransnumeral(word)) { return word; } var singulars = this.singulars, length = singulars.length, tuple, regex, i; for (i = 0; i < length; i++) { tuple = singulars[i]; regex = tuple[0]; if (regex == word || (regex.test && regex.test(word))) { return word.replace(regex, tuple[1]); } } return word; }, classify: function(word) { return Ext.String.capitalize(this.singularize(word)); }, ordinalize: function(number) { var parsed = parseInt(number, 10), mod10 = parsed % 10, mod100 = parsed % 100; if (11 <= mod100 && mod100 <= 13) { return number + "th"; } 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) { if (irregulars.hasOwnProperty(singular)) { this.plural(singular, irregulars[singular]); this.singular(irregulars[singular], singular); } } }); Ext.define('Ext.data.schema.Namer', { mixins: [ 'Ext.mixin.Factoryable' ], requires: [ 'Ext.util.Inflector' ], alias: 'namer.default', isNamer: true, capitalize: function(name) { return Ext.String.capitalize(name); }, fieldRole: function(name) { var match = name.match(this.endsWithIdRe, ''); if (match) { name = name.substr(0, name.length - (match[1] || match[2]).length); } return this.apply('uncapitalize', name); }, idField: function(name) { return this.apply('uncapitalize,singularize', name) + 'Id'; }, instanceName: function(roleName) { return this.apply('underscore', roleName); }, multiRole: function(name) { return this.apply('undotted,uncapitalize,pluralize', name); }, pluralize: function(name) { return Ext.util.Inflector.pluralize(name); }, readerRoot: function(roleName) { return this.apply('uncapitalize', roleName); }, singularize: function(name) { return Ext.util.Inflector.singularize(name); }, storeName: function(roleName) { return this.apply('underscore', roleName); }, uncapitalize: function(name) { return Ext.String.uncapitalize(name); }, underscore: function(name) { return '_' + name; }, uniRole: function(name) { return this.apply('undotted,uncapitalize,singularize', name); }, undotted: function(name) { if (name.indexOf('.') < 0) { return name; } var parts = name.split('.'), index = parts.length; while (index-- > 1) { parts[index] = this.apply('capitalize', parts[index]); } return parts.join(''); }, getterName: function(role) { var name = role.role; if (role && role.isMany) { return name; } return 'get' + this.apply('capitalize', name); }, inverseFieldRole: function(leftType, unique, rightRole, rightType) { var me = this, leftRole = me.apply(unique ? 'uniRole' : 'multiRole', leftType), s1 = me.apply('pluralize', rightRole), s2 = me.apply('undotted,pluralize', rightType); if (s1.toLowerCase() !== s2.toLowerCase()) { leftRole = rightRole + me.apply('capitalize', leftRole); } return leftRole; }, manyToMany: function(relation, leftType, rightType) { var me = this, ret = me.apply('undotted,capitalize,singularize', leftType) + me.apply('undotted,capitalize,pluralize', rightType); if (relation) { ret = me.apply('capitalize', relation + ret); } return ret; }, manyToOne: function(leftType, leftRole, rightType, rightRole) { return this.apply('capitalize,singularize', rightType) + this.apply('capitalize', leftRole); }, matrixRole: function(relation, entityType) { var ret = this.apply(relation ? 'multiRole,capitalize' : 'multiRole', entityType); return relation ? relation + ret : ret; }, oneToOne: function(leftType, leftRole, rightType, rightRole) { return this.apply('undotted,capitalize,singularize', rightType) + this.apply('capitalize', leftRole); }, setterName: function(role) { return 'set' + this.apply('capitalize', role.role); }, endsWithIdRe: /(?:(_id)|[^A-Z](Id))$/, cache: {}, apply: function(operation, name) { var me = this, cache = me.cache, entry = cache[name] || (cache[name] = {}), ret = entry[operation], i, length, operations; if (!ret) { if (operation.indexOf(',') < 0) { ret = me[operation](name); } else { length = (operations = operation.split(',')).length; ret = name; for (i = 0; i < length; ++i) { ret = me.apply(operations[i], ret); } } entry[operation] = ret; } return ret; } }); Ext.define('Ext.data.schema.Schema', { mixins: [ 'Ext.mixin.Factoryable' ], requires: [ 'Ext.util.ObjectTemplate', 'Ext.data.schema.OneToOne', 'Ext.data.schema.ManyToOne', 'Ext.data.schema.ManyToMany', 'Ext.data.schema.Namer' ], alias: 'schema.default', aliasPrefix: 'schema.', isSchema: true, type: 'default', statics: { instances: {}, get: function(config) { var Schema = this, cache = Schema.instances, id = 'default', isString = config && Ext.isString(config), instance, newConfig; if (config) { if (config.isSchema) { return config; } id = isString ? config : (config.id || id); } if (!(instance = cache[id])) { cache[id] = instance = Schema.create(config); instance.id = id; } else if (config && !isString) { if (id !== 'default') { Ext.Error.raise('Only the default Schema instance can be reconfigured'); } newConfig = Ext.merge({}, instance.config); Ext.merge(newConfig, config); instance.setConfig(newConfig); instance.config = newConfig; instance.setConfig = function() { Ext.Error.raise('The schema can only be reconfigured once'); }; } return instance; }, lookupEntity: function(entity) { var ret = null, instances = this.instances, match, name, schema; if (entity) { if (entity.isEntity) { ret = entity.self; } else if (Ext.isFunction(entity)) { ret = entity; } else if (Ext.isString(entity)) { ret = Ext.ClassManager.get(entity); if (ret && (!ret.prototype || !ret.prototype.isEntity)) { ret = null; } if (!ret) { for (name in instances) { schema = instances[name]; match = schema.getEntity(entity); if (match) { if (ret) { Ext.Error.raise('Ambiguous entity name "' + entity + '". Defined by schema "' + ret.schema.type + '" and "' + name + '"'); } ret = match; } } } if (!ret) { Ext.Error.raise('No such Entity "' + entity + '".'); } } } return ret; } }, assocCount: 0, entityCount: 0, config: { defaultIdentifier: null, keyCheckDelay: 10, namer: 'default', namespace: null, proxy: { type: 'ajax', url: '{prefix}/{entityName}' }, urlPrefix: '' }, onClassExtended: function(cls, data) { var alias = data.alias; if (alias && !data.type) { if (!Ext.isString(alias)) { alias = alias[0]; } cls.prototype.type = alias.substring(this.prototype.aliasPrefix.length); } }, constructor: function(config) { this.initConfig(config); this.clear(); }, applyDefaultIdentifier: function(identifier) { return identifier && Ext.Factory.dataIdentifier(identifier); }, applyNamer: function(namer) { var ret = Ext.data.schema.Namer.create(namer); ret.schema = this; return ret; }, applyNamespace: function(namespace) { if (namespace) { var end = namespace.length - 1; if (namespace.charAt(end) !== '.') { namespace += '.'; } } return namespace; }, applyProxy: function(proxy) { return Ext.util.ObjectTemplate.create(proxy); }, eachAssociation: function(fn, scope) { var associations = this.associations, name; for (name in associations) { if (associations.hasOwnProperty(name)) { if (fn.call(scope, name, associations[name]) === false) { break; } } } }, eachEntity: function(fn, scope) { var entities = this.entities, name; for (name in entities) { if (entities.hasOwnProperty(name)) { if (fn.call(scope, name, entities[name].cls) === false) { break; } } } }, getAssociation: function(name) { var entry = this.associations[name]; return entry || null; }, getEntity: function(name) { var entry = this.entityClasses[name] || this.entities[name]; return (entry && entry.cls) || null; }, getEntityName: function(cls) { var ns = this.getNamespace(), index, name; if (typeof cls === 'string') { name = cls; } else { name = cls.$className || null; } if (name) { if (ns) { index = ns.length; if (name.substring(0, index) !== ns) { return name; } } if (index) { name = name.substring(index); } } return name; }, hasAssociations: function(name) { name = name.entityName || name; return !!this.associationEntityMap[name]; }, hasEntity: function(entity) { var name = this.getEntityName(entity); return !!(this.entities[name] || this.entityClasses[name]); }, addMatrix: function(entityType, matrixName, relation, left, right) { var me = this, namer = me.getNamer(), associations = me.associations, entities = me.entities, leftType = left.type, rightType = right.type, leftField = left.field || namer.apply('idField', leftType), rightField = right.field || namer.apply('idField', rightType), leftRole = left.role || namer.matrixRole(relation, leftType), rightRole = right.role || namer.matrixRole(relation, rightType), matrix, leftEntry, rightEntry; leftEntry = entities[leftType] || (entities[leftType] = { cls: null, name: leftType, associations: {} }); rightEntry = entities[rightType] || (entities[rightType] = { cls: null, name: rightType, associations: {} }); ++me.assocCount; associations[matrixName] = matrix = new Ext.data.schema.ManyToMany({ name: matrixName, schema: me, definedBy: entityType, left: { cls: leftEntry.cls, type: leftType, role: leftRole, field: leftField, associationKey: left.associationKey }, right: { cls: rightEntry.cls, type: rightType, role: rightRole, field: rightField, associationKey: right.associationKey } }); leftEntry.associations[matrix.right.role] = matrix.right; rightEntry.associations[matrix.left.role] = matrix.left; if (leftEntry.cls) { me.associationEntityMap[leftEntry.cls.entityName] = true; } if (rightEntry.cls) { me.associationEntityMap[rightEntry.cls.entityName] = true; } me.decorateModel(matrix); }, addReference: function(entityType, referenceField, descr, unique) { var me = this, namer = me.getNamer(), entities = me.entities, associations = me.associations, entityName = entityType.entityName, association = descr.association, legacy = !!descr.legacy, child = descr.child, parent = descr.parent, rightRole = descr.role, rightType = descr.type || parent || child, leftVal = descr.inverse, left = Ext.isString(leftVal) ? { role: leftVal } : leftVal, leftRole = left && left.role, entry, T; if (!rightRole) { if (legacy) { rightRole = namer.apply('uncapitalize', rightType); } else { rightRole = namer.apply('fieldRole', referenceField.name); } } if (!leftRole) { leftRole = namer.inverseFieldRole(entityName, unique, rightRole, rightType); } if (!association) { if (unique) { association = namer.oneToOne(entityType, leftRole, rightType, rightRole); } else { association = namer.manyToOne(entityType, leftRole, rightType, rightRole); } } if (association in associations) { Ext.Error.raise('Duplicate association: "' + association + '" declared by ' + entityName + (referenceField ? ('.' + referenceField.name) : '') + ' (collides with ' + associations[association].definedBy.entityName + ')'); } if (referenceField && referenceField.definedBy === entities[rightType]) { Ext.Error.raise('ForeignKey reference should not be owned by the target model'); } entry = entities[rightType] || (entities[rightType] = { cls: null, name: rightType, associations: {} }); T = unique ? Ext.data.schema.OneToOne : Ext.data.schema.ManyToOne; association = new T({ name: association, owner: child ? 'left' : (parent ? 'right' : null), definedBy: entityType, schema: me, field: referenceField, nullable: referenceField ? !!referenceField.allowBlank : true, legacy: descr.legacy, left: { cls: entityType, type: entityName, role: leftRole, extra: left }, right: { cls: entry.cls, type: rightType, role: rightRole, extra: descr } }); entityType.associations[rightRole] = association.right; entry.associations[leftRole] = association.left; if (referenceField) { referenceField.reference = association.right; entityType.references.push(referenceField); } ++me.assocCount; me.associationEntityMap[entityName] = true; if (entry.cls) { me.associationEntityMap[entry.cls.entityName] = true; } associations[association.name] = association; if (association.right.cls) { me.decorateModel(association); } }, privates: { addEntity: function(entityType) { var me = this, entities = me.entities, entityName = entityType.entityName, entry = entities[entityName], fields = entityType.fields, associations, field, i, length, name; if (!entry) { entities[entityName] = entry = { name: entityName, associations: {} }; } else if (entry.cls) { Ext.Error.raise('Duplicate entity name "' + entityName + '": ' + entry.cls.$className + ' and ' + entityType.$className); } else { associations = entry.associations; for (name in associations) { associations[name].inverse.cls = entityType; me.associationEntityMap[entityName] = true; me.decorateModel(associations[name].association); } } entry.cls = entityType; entityType.prototype.associations = entityType.associations = entry.associations; me.entityClasses[entityType.$className] = entry; ++me.entityCount; for (i = 0 , length = fields.length; i < length; ++i) { field = fields[i]; if (field.reference) { me.addReferenceDescr(entityType, field); } } }, addMatrices: function(entityType, matrices) { var me = this, i, length, matrixName; if (Ext.isString(matrices)) { me.addMatrixDescr(entityType, null, matrices); } else if (matrices[0]) { for (i = 0 , length = matrices.length; i < length; ++i) { me.addMatrixDescr(entityType, null, matrices[i]); } } else { for (matrixName in matrices) { me.addMatrixDescr(entityType, matrixName, matrices[matrixName]); } } }, addMatrixDescr: function(entityType, matrixName, matrixDef) { var me = this, entityName = entityType.entityName, associations = me.associations, namer = me.getNamer(), left = matrixDef.left, right = matrixDef.right, last, relation; if (Ext.isString(matrixDef)) { if (matrixDef.charAt(0) === '#') { left = { type: entityName }; right = { type: matrixDef.substring(1) }; } else if (matrixDef.charAt(last = matrixDef.length - 1) === '#') { left = { type: matrixDef.substring(0, last) }; right = { type: entityName }; } else if (namer.apply('multiRole', entityName) < namer.apply('multiRole', matrixDef)) { left = { type: entityName }; right = { type: matrixDef }; } else { left = { type: matrixDef }; right = { type: entityName }; } } else { Ext.Assert.isString(matrixDef.type, 'No "type" for manyToMany in ' + entityName); relation = matrixDef.relation; if (left || (!right && namer.apply('multiRole', entityName) < namer.apply('multiRole', matrixDef.type))) { if (!left || left === true) { left = { type: entityName }; } else { left = Ext.apply({ type: entityName }, left); } right = matrixDef; } else { if (!right || right === true) { right = { type: entityName }; } else { right = Ext.apply({ type: entityName }, right); } left = matrixDef; } } if (!matrixName) { matrixName = namer.manyToMany(relation, left.type, right.type); } if (!(matrixName in associations)) { me.addMatrix(entityType, matrixName, relation, left, right); } else { var entry = associations[matrixName], before = [ entry.kind, entry.left.type, entry.left.role, entry.left.field, entry.right.type, entry.right.role, entry.right.field ].join('|'); delete associations[matrixName]; me.addMatrix(entityType, matrixName, relation, left, right); var after = associations[matrixName]; associations[matrixName] = entry; entry.left.cls.associations[entry.right.role] = entry.right; entry.right.cls.associations[entry.left.role] = entry.left; --me.assocCount; after = [ after.kind, after.left.type, after.left.role, after.left.field, after.right.type, after.right.role, after.right.field ].join('|'); if (before != after) { Ext.log.warn(matrixName + '(' + entry.definedBy.entityName + '): ' + before); Ext.log.warn(matrixName + '(' + entityName + '): ' + after); Ext.Error.raise('Conflicting association: "' + matrixName + '" declared by ' + entityName + ' was previously declared by ' + entry.definedBy.entityName); } } }, addReferenceDescr: function(entityType, referenceField) { var me = this, descr = referenceField.$reference; if (Ext.isString(descr)) { descr = { type: descr }; } else { descr = Ext.apply({}, descr); } if (descr.legacy) { if (descr.single) { me.addLegacySingle(entityType, descr); } else { me.addLegacyHasMany(entityType, descr); } } else { me.addReference(entityType, referenceField, descr, referenceField.unique); } }, addPending: function(name, entityType, assoc, type) { var pending = this.pending; if (!pending[name]) { pending[name] = []; } pending[name].push([ entityType, assoc, type ]); }, addLegacyBelongsTo: function(entityType, assoc) { this.addLegacySingle(entityType, assoc); }, addLegacyHasOne: function(entityType, assoc) { this.addLegacySingle(entityType, assoc); }, addLegacySingle: function(entityType, assoc) { var foreignKey, name, referenceField; assoc = this.constructLegacyAssociation(entityType, assoc); assoc.single = true; name = assoc.type; foreignKey = assoc.foreignKey || (name.toLowerCase() + '_id'); referenceField = entityType.getField(foreignKey); if (referenceField) { referenceField.$reference = assoc; } this.addReference(entityType, referenceField, assoc, true); }, addLegacyHasMany: function(entityType, assoc) { var me = this, entities = me.entities, pending = me.pending, associationKey = assoc.associationKey, cls, name, referenceField, target, foreignKey, assocName; assoc = this.constructLegacyAssociation(entityType, assoc); name = assoc.type; target = entities[name]; if (target && target.cls) { assoc.type = entityType.entityName; foreignKey = assoc.foreignKey || (assoc.type.toLowerCase() + '_id'); cls = target.cls; referenceField = cls.getField(foreignKey); assoc.inverse = assoc || {}; assocName = assoc.name; if (assocName || associationKey) { if (assocName) { assoc.inverse.role = assocName; } if (associationKey) { assoc.inverse.associationKey = associationKey; } } if (referenceField) { referenceField.$reference = assoc; } me.addReference(cls, referenceField, assoc, false); } else { if (!pending[name]) { pending[name] = []; } pending[name].push([ entityType, assoc ]); } }, constructLegacyAssociation: function(entityType, assoc) { if (Ext.isString(assoc)) { assoc = { model: assoc }; } assoc.legacy = true; assoc.type = this.getEntityName(assoc.model); var name = assoc.associatedName || assoc.name; if (name) { assoc.role = name; } return assoc; }, afterLegacyAssociations: function(cls) { var pending = this.pending, name = cls.entityName, mine = pending[name], i, len; if (mine) { for (i = 0 , len = mine.length; i < len; ++i) { this.addLegacyHasMany.apply(this, mine[i]); } delete pending[name]; } }, clear: function(clearNamespace) { var me = this, timer = me.timer; delete me.setConfig; if (timer) { window.clearTimeout(timer); me.timer = null; } me.associations = {}; me.associationEntityMap = {}; me.entities = {}; me.entityClasses = {}; me.pending = {}; me.assocCount = me.entityCount = 0; if (clearNamespace) { me.setNamespace(null); } }, constructProxy: function(Model) { var me = this, data = Ext.Object.chain(Model), proxy = me.getProxy(); data.schema = me; data.prefix = me.getUrlPrefix(); return proxy.apply(data); }, applyDecoration: function(role) { var me = this, cls = role.inverse.cls, namer = me.getNamer(), getterName, setterName, proto; if (cls && !role.decorated) { role.decorated = true; proto = cls.prototype; if (!(getterName = role.getterName)) { role.getterName = getterName = namer.getterName(role); } proto[getterName] = role.createGetter(); if (role.createSetter) { if (!(setterName = role.setterName)) { role.setterName = setterName = namer.setterName(role); } proto[setterName] = role.createSetter(); } } }, decorateModel: function(association) { this.applyDecoration(association.left); this.applyDecoration(association.right); }, processKeyChecks: function(processAll) { var me = this, keyCheckQueue = me.keyCheckQueue, timer = me.timer, len, i, item; if (timer) { window.clearTimeout(timer); me.timer = null; } if (!keyCheckQueue) { return; } do { keyCheckQueue = me.keyCheckQueue; me.keyCheckQueue = []; for (i = 0 , len = keyCheckQueue.length; i < len; ++i) { item = keyCheckQueue[i]; item.role.checkKeyForDrop(item.record); } } while (processAll && me.keyCheckQueue.length); }, queueKeyCheck: function(record, role) { var me = this, keyCheckQueue = me.keyCheckQueue, timer = me.timer; if (!keyCheckQueue) { me.keyCheckQueue = keyCheckQueue = []; } keyCheckQueue.push({ record: record, role: role }); if (!timer) { me.timer = timer = Ext.Function.defer(me.processKeyChecks, me.getKeyCheckDelay(), me); } }, rankEntities: function() { var me = this, entities = me.entities, entityNames = Ext.Object.getKeys(entities), length = entityNames.length, entityType, i; me.nextRank = 1; entityNames.sort(); for (i = 0; i < length; ++i) { entityType = entities[entityNames[i]].cls; if (!entityType.rank) { me.rankEntity(entityType); } } me.topoStack = null; }, rankEntity: function(entityType) { var associations = entityType.associations, associatedType, role, roleName; var topoStack = this.topoStack || (this.topoStack = []), entityName = entityType.entityName; topoStack.push(entityName); if (entityType.rank === 0) { Ext.Error.raise(entityName + " has circular foreign-key references: " + topoStack.join(" --> ")); } entityType.rank = 0; for (roleName in associations) { role = associations[roleName]; if (!role.left && role.association.field) { associatedType = role.cls; if (!associatedType.rank) { this.rankEntity(associatedType); } } } entityType.rank = this.nextRank++; topoStack.pop(); } } }); Ext.define('Ext.data.AbstractStore', { mixins: [ 'Ext.mixin.Observable', 'Ext.mixin.Factoryable' ], requires: [ 'Ext.util.Collection', 'Ext.data.schema.Schema', 'Ext.util.Filter' ], factoryConfig: { defaultType: 'store', type: 'store' }, $configPrefixed: false, $configStrict: false, config: { filters: null, autoDestroy: undefined, storeId: null, statefulFilters: false, sorters: null, remoteSort: { lazy: true, $value: false }, remoteFilter: { lazy: true, $value: false }, groupField: undefined, groupDir: 'ASC', grouper: null, pageSize: 25 }, currentPage: 1, loading: false, isDestroyed: false, isStore: true, updating: 0, constructor: function(config) { var me = this, storeId; me.isInitializing = true; me.mixins.observable.constructor.call(me, config); me.isInitializing = false; storeId = me.getStoreId(); if (!storeId && (config && config.id)) { me.setStoreId(storeId = config.id); } if (storeId) { Ext.data.StoreManager.register(me); } }, getCount: function() { return this.getData().getCount(); }, rangeCached: function(start, end) { return this.getData().getCount() >= Math.max(start, end); }, find: function(property, value, startIndex, anyMatch, caseSensitive, exactMatch) { var startsWith = !anyMatch, endsWith = !!(startsWith && exactMatch); return this.getData().findIndex(property, value, startIndex, startsWith, endsWith, !caseSensitive); }, findRecord: function() { var me = this, index = me.find.apply(me, arguments); return index !== -1 ? me.getAt(index) : null; }, findExact: function(property, value, start) { return this.getData().findIndexBy(function(rec) { return rec.isEqual(rec.get(property), value); }, this, start); }, findBy: function(fn, scope, start) { return this.getData().findIndexBy(fn, scope, start); }, getAt: function(index) { return this.getData().getAt(index) || null; }, getRange: function(start, end, options) { var result = this.getData().getRange(start, Ext.isNumber(end) ? end + 1 : end); if (options && options.callback) { options.callback.call(options.scope || this, result, start, end, options); } return result; }, getFilters: function( autoCreate) { var result = this.callParent(); if (!result && autoCreate !== false) { this.setFilters([]); result = this.callParent(); } return result; }, applyFilters: function(filters, filtersCollection) { var created; if (!filtersCollection) { filtersCollection = this.createFiltersCollection(); created = true; } filtersCollection.add(filters); if (created) { this.onRemoteFilterSet(filtersCollection, this.getRemoteFilter()); } return filtersCollection; }, getSorters: function( autoCreate) { var result = this.callParent(); if (!result && autoCreate !== false) { this.setSorters([]); result = this.callParent(); } return result; }, applySorters: function(sorters, sortersCollection) { var created; if (!sortersCollection) { sortersCollection = this.createSortersCollection(); created = true; } sortersCollection.add(sorters); if (created) { this.onRemoteSortSet(sortersCollection, this.getRemoteSort()); } return sortersCollection; }, filter: function(filters, value, supressEvent) { if (Ext.isString(filters)) { filters = { property: filters, value: value }; } this.suppressNextFilter = !!supressEvent; this.getFilters().add(filters); this.suppressNextFilter = false; }, removeFilter: function(filter, supressEvent) { var me = this, filters = me.getFilters(); me.suppressNextFilter = !!supressEvent; if (filter instanceof Ext.util.Filter) { filters.remove(filter); } else { filters.removeByKey(filter); } me.suppressNextFilter = false; }, updateRemoteSort: function(remoteSort) { this.onRemoteSortSet(this.getSorters(false), remoteSort); }, updateRemoteFilter: function(remoteFilter) { this.onRemoteFilterSet(this.getFilters(false), remoteFilter); }, addFilter: function(filters, supressEvent) { this.suppressNextFilter = !!supressEvent; this.getFilters().add(filters); this.suppressNextFilter = false; }, filterBy: function(fn, scope) { this.getFilters().add({ filterFn: fn, scope: scope || this }); }, clearFilter: function(supressEvent) { var me = this, filters = me.getFilters(false); if (!filters || filters.getCount() === 0) { return; } me.suppressNextFilter = !!supressEvent; filters.removeAll(); me.suppressNextFilter = false; }, isFiltered: function() { return this.getFilters().getCount() > 0; }, isSorted: function() { var sorters = this.getSorters(false); return !!(sorters && sorters.length > 0) || this.isGrouped(); }, addFieldTransform: function(sorter) { if (sorter.getTransform()) { return; } var fieldName = sorter.getProperty(), Model = this.getModel(), field, sortType; if (Model) { field = Model.getField(fieldName); sortType = field ? field.getSortType() : null; } if (sortType && sortType !== Ext.identityFn) { sorter.setTransform(sortType); } }, beginUpdate: function() { if (!this.updating++) { this.fireEvent('beginupdate'); } }, endUpdate: function() { if (this.updating && !--this.updating) { this.fireEvent('endupdate'); this.onEndUpdate(); } }, getState: function() { var me = this, sorters = [], filters = me.getFilters(), grouper = me.getGrouper(), filterState, hasState, result; me.getSorters().each(function(s) { sorters[sorters.length] = s.getState(); hasState = true; }); if (me.statefulFilters && me.saveStatefulFilters) { hasState = true; filterState = []; filters.each(function(f) { filterState[filterState.length] = f.getState(); }); } if (grouper) { hasState = true; } if (hasState) { result = {}; if (sorters.length) { result.sorters = sorters; } if (filterState) { result.filters = filterState; } if (grouper) { result.grouper = grouper.getState(); } } return result; }, applyState: function(state) { var me = this, stateSorters = state.sorters, stateFilters = state.filters, stateGrouper = state.grouper; if (stateSorters) { me.getSorters().replaceAll(stateSorters); } if (stateFilters) { me.saveStatefulFilters = true; me.getFilters().replaceAll(stateFilters); } if (stateGrouper) { this.setGrouper(stateGrouper); } }, hasPendingLoad: Ext.emptyFn, isLoaded: Ext.emptyFn, isLoading: Ext.emptyFn, destroy: function() { var me = this; me.clearListeners(); if (me.getStoreId()) { Ext.data.StoreManager.unregister(me); } me.onDestroy(); me.callParent(); }, sort: function(field, direction, mode) { var me = this; if (arguments.length === 0) { if (me.getRemoteSort()) { me.attemptLoad(); } else { me.forceLocalSort(); } } else { me.getSorters().addSort(field, direction, mode); } }, onBeforeCollectionSort: function(store, sorters) { if (sorters) { this.fireEvent('beforesort', this, sorters.getRange()); } }, onSorterEndUpdate: function() { var me = this, sorters; sorters = me.getSorters(false); if (me.settingGroups || !sorters) { return; } sorters = sorters.getRange(); if (sorters.length) { if (me.getRemoteSort()) { me.attemptLoad({ callback: function() { me.fireEvent('sort', me, sorters); } }); } else { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); me.fireEvent('sort', me, sorters); } } else { me.fireEvent('sort', me, sorters); } }, onFilterEndUpdate: function() { var me = this, suppressNext = me.suppressNextFilter; if (me.getRemoteFilter()) { me.getFilters().each(function(filter) { if (filter.getInitialConfig().filterFn) { Ext.Error.raise('Unable to use a filtering function in conjunction with remote filtering.'); } }); me.currentPage = 1; if (!suppressNext) { me.attemptLoad(); } } else if (!suppressNext) { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); } if (me.trackStateChanges) { me.saveStatefulFilters = true; } me.fireEvent('filterchange', me, me.getFilters().getRange()); }, updateGroupField: function(field) { if (field) { this.setGrouper({ property: field, direction: this.getGroupDir() }); } else { this.setGrouper(null); } }, getGrouper: function() { return this.getData().getGrouper(); }, group: function(grouper, direction) { var me = this, sorters = me.getSorters(false), change = grouper || (sorters && sorters.length); if (grouper && typeof grouper === 'string') { grouper = { property: grouper, direction: direction || me.getGroupDir() }; } me.settingGroups = true; me.getData().setGrouper(grouper); delete me.settingGroups; if (me.isLoadBlocked()) { return; } if (change) { if (me.getRemoteSort()) { me.attemptLoad({ scope: me, callback: me.fireGroupChange }); } else { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); me.fireGroupChange(); } } else { me.fireGroupChange(); } }, fireGroupChange: function() { this.fireEvent('groupchange', this, this.getGrouper()); }, clearGrouping: function() { this.group(null); }, getGroupField: function() { var grouper = this.getGrouper(), group = ''; if (grouper) { group = grouper.getProperty(); } return group; }, isGrouped: function() { return !!this.getGrouper(); }, applyGrouper: function(grouper) { this.group(grouper); return this.getData().getGrouper(); }, getGroups: function() { return this.getData().getGroups(); }, onEndUpdate: Ext.emptyFn, privates: { loadsSynchronously: Ext.privateFn, onRemoteFilterSet: function(filters, remoteFilter) { if (filters) { filters[remoteFilter ? 'on' : 'un']('endupdate', this.onFilterEndUpdate, this); } }, onRemoteSortSet: function(sorters, remoteSort) { var me = this; if (sorters) { sorters[remoteSort ? 'on' : 'un']('endupdate', me.onSorterEndUpdate, me); me.getData()[remoteSort ? 'un' : 'on']('beforesort', me.onBeforeCollectionSort, me); } } }, deprecated: { 5: { methods: { destroyStore: function() { this.destroy(); } } } } }); Ext.define('Ext.data.Error', { isError: true, $configPrefixed: false, config: { field: null, message: '' }, constructor: function(config) { this.initConfig(config); this.msg = this.message; } }); Ext.define('Ext.data.ErrorCollection', { extend: 'Ext.util.MixedCollection', alternateClassName: 'Ext.data.Errors', requires: [ 'Ext.data.Error' ], init: function(record) { var me = this, fields = record.fields, data = record.data, before, field, item, i, len, msg, val, name; for (i = 0 , len = fields.length; i < len; ++i) { field = fields[i]; name = field.name; val = data[name]; if (field.validate && !field.validate.$nullFn) { before = me.length; msg = field.validate(val, null, me); if (before === me.length && msg !== true) { me.add(name, msg); } } } return me; }, add: function(key, value) { var me = this, defaultMessage = Ext.data.field.Field.defaultInvalidMessage, obj = key, current; if (Ext.isString(key)) { obj = new Ext.data.Error({ field: key, message: value || defaultMessage }); } else { if (!(obj.isError)) { obj = new Ext.data.Error({ field: obj.field || obj.name, message: obj.error || obj.message || obj.msg || defaultMessage }); } key = obj.field; } current = me.get(key); if (current) { if (Ext.isArray(current)) { current.push(obj); return current; } me.removeAtKey(key); obj = [ current, obj ]; obj.field = key; obj = [ obj ]; } return me.callParent([ obj ]); }, getKey: function(item) { return item.field; }, isValid: function() { return this.length === 0; }, getByField: function(fieldName) { var values = this.get(fieldName); if (values && !Ext.isArray(values)) { values = [ values ]; } return values || []; } }); Ext.define('Ext.data.operation.Operation', { alternateClassName: 'Ext.data.Operation', isOperation: true, config: { synchronous: false, url: '', params: undefined, callback: undefined, scope: undefined, resultSet: null, response: null, request: null, records: null, id: undefined, proxy: null, batch: null, recordCreator: null, internalCallback: null, internalScope: null }, order: 0, foreignKeyDirection: 1, started: false, running: false, complete: false, success: undefined, exception: false, error: undefined, idPrefix: 'ext-operation-', constructor: function(config) { var scope = config && config.scope; this.initConfig(config); if (config) { config.scope = scope; } if (scope) { this.setScope(scope); this.initialConfig.scope = scope; } this._internalId = Ext.id(this, this.idPrefix); }, getAction: function() { return this.action; }, execute: function() { var me = this; delete me.error; delete me.success; me.complete = me.exception = false; me.setStarted(); return me.request = me.doExecute(); }, doExecute: Ext.emptyFn, abort: function() { var me = this, request = me.request; if (me.running && request) { me.getProxy().abort(request); me.request = null; } }, process: function(resultSet, request, response, autoComplete) { var me = this; autoComplete = autoComplete !== false; me.setResponse(response); me.setResultSet(resultSet); if (resultSet.getSuccess()) { me.doProcess(resultSet, request, response); me.setSuccessful(autoComplete); } else if (autoComplete) { me.setException(resultSet.getMessage()); } }, _commitSetOptions: { convert: true, commit: true }, doProcess: function(resultSet, request, response) { var me = this, commitSetOptions = me._commitSetOptions, clientRecords = me.getRecords(), clientLen = clientRecords.length, clientIdProperty = clientRecords[0].clientIdProperty, serverRecords = resultSet.getRecords(), serverLen = serverRecords ? serverRecords.length : 0, clientMap, serverRecord, clientRecord, i; if (serverLen && clientIdProperty) { clientMap = Ext.Array.toValueMap(clientRecords, 'id'); for (i = 0; i < serverLen; ++i) { serverRecord = serverRecords[i]; clientRecord = clientMap[serverRecord[clientIdProperty]]; if (clientRecord) { delete clientMap[clientRecord.id]; delete serverRecord[clientIdProperty]; clientRecord.set(serverRecord, commitSetOptions); } else { Ext.log.warn('Ignoring server record: ' + Ext.encode(serverRecord)); } } for (i in clientMap) { clientMap[i].commit(); } } else { for (i = 0; i < clientLen; ++i) { clientRecord = clientRecords[i]; if (serverLen === 0 || !(serverRecord = serverRecords[i])) { clientRecord.commit(); } else { clientRecord.set(serverRecord, commitSetOptions); } } } }, setStarted: function() { this.started = this.running = true; }, setCompleted: function() { var me = this, proxy = me.getProxy(); me.complete = true; me.running = false; me.triggerCallbacks(); if (proxy) { proxy.completeOperation(me); } }, setSuccessful: function(complete) { this.success = true; if (complete) { this.setCompleted(); } }, setException: function(error) { var me = this; me.exception = true; me.success = me.running = false; me.error = error; me.setCompleted(); }, triggerCallbacks: function() { var me = this, callback = me.getInternalCallback(); if (callback) { callback.call(me.getInternalScope() || me, me); me.setInternalCallback(null); me.setInternalScope(null); } if (callback = me.getCallback()) { callback.call(me.getScope() || me, me.getRecords(), me, me.wasSuccessful()); me.setCallback(null); me.setScope(null); } }, hasException: function() { return this.exception; }, getError: function() { return this.error; }, getRecords: function() { var resultSet; return this._records || ((resultSet = this.getResultSet()) ? resultSet.getRecords() : null); }, isStarted: function() { return this.started; }, isRunning: function() { return this.running; }, isComplete: function() { return this.complete; }, wasSuccessful: function() { return this.isComplete() && this.success === true; }, allowWrite: function() { return true; } }); Ext.define('Ext.data.operation.Create', { extend: 'Ext.data.operation.Operation', alias: 'data.operation.create', action: 'create', isCreateOperation: true, order: 10, config: { recordCreator: Ext.identityFn }, doExecute: function() { return this.getProxy().create(this); } }); Ext.define('Ext.data.operation.Destroy', { extend: 'Ext.data.operation.Operation', alias: 'data.operation.destroy', action: 'destroy', isDestroyOperation: true, order: 30, foreignKeyDirection: -1, doProcess: function() { var clientRecords = this.getRecords(), clientLen = clientRecords.length, i; for (i = 0; i < clientLen; ++i) { clientRecords[i].setErased(); } }, doExecute: function() { return this.getProxy().erase(this); }, getRecordData: function(record, operation) { var data = {}, idField = record.idField, nameProperty = this.getNameProperty() || 'name'; data[idField[nameProperty]] = record.id; return data; } }); Ext.define('Ext.data.operation.Read', { extend: 'Ext.data.operation.Operation', alias: 'data.operation.read', action: 'read', isReadOperation: true, config: { filters: undefined, sorters: undefined, grouper: undefined, start: undefined, limit: undefined, page: undefined, addRecords: false }, doExecute: function() { return this.getProxy().read(this); }, doProcess: Ext.emptyFn, allowWrite: function() { return false; } }); Ext.define('Ext.data.operation.Update', { extend: 'Ext.data.operation.Operation', alias: 'data.operation.update', action: 'update', isUpdateOperation: true, order: 20, config: { recordCreator: Ext.identityFn }, doExecute: function() { return this.getProxy().update(this); } }); Ext.define('Ext.data.SortTypes', { singleton: true, none: Ext.identityFn, stripCommasRe: /,/g, stripTagsRE: /<\/?[^>]+>/gi, asText: function(s) { return (s != null) ? String(s).replace(this.stripTagsRe, '') : '\x00'; }, asUCText: function(s) { return (s != null) ? String(s).toUpperCase().replace(this.stripTagsRe, '') : '\x00'; }, asUCString: function(s) { return (s != null) ? String(s).toUpperCase() : '\x00'; }, 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(this.stripCommasRe, '')); return isNaN(val) ? 0 : val; }, asInt: function(s) { var val = parseInt(String(s).replace(this.stripCommasRe, ''), 10); return isNaN(val) ? 0 : val; } }); Ext.define('Ext.data.validator.Validator', { mixins: [ 'Ext.mixin.Factoryable' ], alias: 'data.validator.base', isValidator: true, type: 'base', statics: { all: {}, register: function(name, cls) { var all = this.all; all[name.toUpperCase()] = all[name.toLowerCase()] = all[name] = cls.prototype; } }, onClassExtended: function(cls, data) { if (data.type) { Ext.data.validator.Validator.register(data.type, cls); } }, constructor: function(config) { if (typeof config === 'function') { this.fnOnly = true; this.validate = config; } else { this.initConfig(config); } }, validate: function() { return true; }, clone: function() { var me = this; if (me.fnOnly) { return new Ext.data.validator.Validator(me.validate); } return new me.self(me.getCurrentConfig()); } }, function() { this.register(this.prototype.type, this); }); Ext.define('Ext.data.field.Field', { mixins: [ 'Ext.mixin.Factoryable' ], requires: [ 'Ext.data.SortTypes', 'Ext.data.validator.Validator' ], alternateClassName: 'Ext.data.Field', alias: 'data.field.auto', aliasPrefix: 'data.field.', type: 'auto', factoryConfig: { defaultProperty: 'name' }, isDataField: true, isField: true, allowBlank: true, allowNull: false, critical: false, defaultInvalidMessage: 'This field is invalid', defaultValue: undefined, definedBy: null, depends: null, dependents: null, mapping: null, name: null, ordinal: undefined, persist: null, reference: null, unique: false, rank: null, stripRe: /[\$,%]/g, calculated: false, evil: false, identifier: false, onClassExtended: function(cls, data) { var sortType = data.sortType, proto = cls.prototype, superValidators = proto.validators, validators = data.validators; if (sortType && Ext.isString(sortType)) { proto.sortType = Ext.data.SortTypes[sortType]; } if (validators) { if (!Ext.isArray(validators)) { validators = [ validators ]; } delete data.validators; if (superValidators) { validators = superValidators.concat(validators); } proto.validators = validators; } }, argumentNamesRe: /^function\s+\(\s*([^,\)\s]+)/, calculateRe: /[^\.a-z0-9_]([a-z_][a-z_0-9]*)\.([a-z_][a-z_0-9]*)/gi, constructor: function(config) { var me = this, calculateRe = me.calculateRe, calculate, calculated, defaultValue, sortType, depends, map, match, dataProp, str, fld, validators; if (config) { if (Ext.isString(config)) { me.name = config; } else { validators = config.validators; if (validators) { delete config.validators; me.instanceValidators = validators; } Ext.apply(me, config); } } if (!me.allowNull) { me.allowNull = !!me.reference; } calculate = me.calculate; depends = me.depends; if (calculate) { me.convert = me.doCalculate; if (!depends) { if (!(depends = calculate.$depends)) { map = {}; str = calculate.toString(); calculate.$depends = depends = []; match = me.argumentNamesRe.exec(str); dataProp = match ? match[1] : 'data'; while ((match = calculateRe.exec(str))) { if (dataProp === match[1] && !map[fld = match[2]]) { map[fld] = 1; depends.push(fld); } } } me.depends = depends; } } defaultValue = me.defaultValue; if (me.convert) { me.calculated = calculated = me.convert.length > 1; me.evil = calculated && !depends; } if (me.persist === null) { me.persist = !calculate; } sortType = me.sortType; if (!me.sortType) { me.sortType = Ext.data.SortTypes.none; } else if (Ext.isString(sortType)) { me.sortType = Ext.data.SortTypes[sortType]; } if (depends && typeof depends === 'string') { me.depends = [ depends ]; } me.cloneDefaultValue = defaultValue !== undefined && (Ext.isDate(defaultValue) || Ext.isArray(defaultValue) || Ext.isObject(defaultValue)); }, setModelValidators: function(modelValidators) { this._validators = null; this.modelValidators = modelValidators; }, compileValidators: function() { var me = this; me._validators = []; me.constructValidators(me.validators); me.constructValidators(me.modelValidators); me.constructValidators(me.instanceValidators); }, constructValidators: function(validators) { if (validators) { if (!(validators instanceof Array)) { validators = [ validators ]; } var length = validators.length, all = this._validators, i, item; for (i = 0; i < length; ++i) { item = validators[i]; if (item.fn) { item = item.fn; } all.push(Ext.Factory.dataValidator(item)); } } }, collate: function(value1, value2) { var me = this, lhs = value1, rhs = value2; if (me.sortType) { lhs = me.sortType(lhs); rhs = me.sortType(rhs); } return (lhs === rhs) ? 0 : ((lhs < rhs) ? -1 : 1); }, compare: function(value1, value2) { return (value1 === value2) ? 0 : ((value1 < value2) ? -1 : 1); }, isEqual: function(value1, value2) { return this.compare(value1, value2) === 0; }, convert: null, serialize: null, validate: function(value, separator, errors) { var me = this, ret = '', result, validator, validators, length, i; if (!me._validators) { me.compileValidators(); } validators = me._validators; for (i = 0 , length = validators.length; i < length; ++i) { validator = validators[i]; result = validator.validate(value); if (result !== true) { result = result || me.defaultInvalidMessage; if (errors) { errors.add(me.name, result); ret = ret || result; } else if (separator) { if (ret) { ret += separator; } ret += result; } else { ret = result; break; } } } return ret || true; }, doCalculate: function(v, rec) { return rec ? this.calculate(rec.data) : v; }, getName: function() { return this.name; }, getAllowBlank: function() { return this.allowBlank; }, getAllowNull: function() { return this.allowNull; }, getConvert: function() { return this.convert; }, getDefaultValue: function() { return this.defaultValue; }, getDepends: function() { return this.depends; }, getMapping: function() { return this.mapping; }, hasMapping: function() { var map = this.mapping; return !!(map || map === 0); }, getPersist: function() { return this.persist; }, getSortType: function() { return this.sortType; }, getType: function() { return 'auto'; }, deprecated: { 5.1: { methods: { getSortDir: function() { return this.sortDir; } } } } }); Ext.define('Ext.data.field.Boolean', { extend: 'Ext.data.field.Field', alias: [ 'data.field.bool', 'data.field.boolean' ], isBooleanField: true, trueRe: /^\s*(?:true|yes|on|1)\s*$/i, convert: function(v) { if (typeof v === 'boolean') { return v; } if (this.allowNull && (v === undefined || v === null || v === '')) { return null; } return this.trueRe.test(String(v)); }, getType: function() { return 'bool'; } }); Ext.define('Ext.data.field.Date', { extend: 'Ext.data.field.Field', alias: 'data.field.date', sortType: 'asDate', isDateField: true, dateFormat: null, dateReadFormat: null, dateWriteFormat: null, compare: function(lhs, rhs) { var lhsIsDate = lhs instanceof Date, rhsIsDate = rhs instanceof Date, result; if (rhsIsDate && lhsIsDate) { result = lhs.getTime() - rhs.getTime(); if (result === 0) { result = 0; } else { result = result < 0 ? -1 : 1; } } else if (lhsIsDate === rhsIsDate) { result = 0; } else { result = lhsIsDate ? 1 : -1; } return result; }, convert: function(v) { if (!v) { return null; } if (v instanceof Date) { return v; } var dateFormat = this.dateReadFormat || this.dateFormat, parsed; if (dateFormat) { return Ext.Date.parse(v, dateFormat); } parsed = Date.parse(v); return parsed ? new Date(parsed) : null; }, serialize: function(value) { var result = null, format; if (Ext.isDate(value)) { format = this.getDateWriteFormat(); result = format ? Ext.Date.format(value, format) : value; } return result; }, getDateFormat: function() { return this.dateFormat; }, getDateReadFormat: function() { return this.dateReadFormat; }, getDateWriteFormat: function() { var me = this; if (me.hasOwnProperty('dateWriteFormat')) { return me.dateWriteFormat; } if (me.hasOwnProperty('dateFormat')) { return me.dateFormat; } return me.dateWriteFormat || me.dateFormat || 'timestamp'; }, getType: function() { return 'date'; } }); Ext.define('Ext.data.field.Integer', { extend: 'Ext.data.field.Field', alias: [ 'data.field.int', 'data.field.integer' ], isNumeric: true, isIntegerField: true, numericType: 'int', convert: function(v) { if (typeof v === 'number') { return this.getNumber(v); } var empty = v === undefined || v === null || v === '', allowNull = this.allowNull, out; if (empty) { out = allowNull ? null : 0; } else { out = this.parse(v); if (allowNull && isNaN(out)) { out = null; } } return out; }, getNumber: function(v) { return parseInt(v, 10); }, getType: function() { return this.numericType; }, parse: function(v) { return parseInt(String(v).replace(this.stripRe, ''), 10); }, sortType: function(s) { if (s == null) { s = Infinity; } return s; } }); Ext.define('Ext.data.field.Number', { extend: 'Ext.data.field.Integer', alias: [ 'data.field.float', 'data.field.number' ], isIntegerField: false, isNumberField: true, numericType: 'float', getNumber: Ext.identityFn, parse: function(v) { return parseFloat(String(v).replace(this.stripRe, '')); } }); Ext.define('Ext.data.field.String', { extend: 'Ext.data.field.Field', alias: 'data.field.string', sortType: 'asUCString', isStringField: true, convert: function(v) { var defaultValue = this.allowNull ? null : ''; return (v === undefined || v === null) ? defaultValue : String(v); }, getType: function() { return 'string'; } }); Ext.define('Ext.data.identifier.Generator', { 'abstract': true, mixins: [ 'Ext.mixin.Factoryable' ], alias: 'data.identifier.default', factoryConfig: { defaultType: 'sequential' }, isGenerator: true, config: { id: null }, constructor: function(config) { var me = this, cache, id; me.initConfig(config); id = me.getId(); if (id) { cache = (config && config.cache) || Ext.data.identifier.Generator.all; cache[id] = me; } }, privates: { clone: function(config) { var cfg = this.getInitialConfig(); cfg = config ? Ext.apply({}, config, cfg) : cfg; return new this.self(cfg); }, statics: { all: {} } } }, function() { var Generator = this, Factory = Ext.Factory, factory = Factory.dataIdentifier; Factory.dataIdentifier = function(config) { var id = Ext.isString(config) ? config : (config && config.id), existing = id && ((config && config.cache) || Generator.all)[id]; return existing || factory(config); }; }); Ext.define('Ext.data.identifier.Sequential', { extend: 'Ext.data.identifier.Generator', alias: 'data.identifier.sequential', config: { increment: 1, prefix: null, seed: 1 }, generate: function() { var me = this, seed = me._seed, prefix = me._prefix; me._seed += me._increment; return (prefix !== null) ? prefix + seed : seed; } }); Ext.define('Ext.data.Model', { alternateClassName: 'Ext.data.Record', requires: [ 'Ext.data.ErrorCollection', 'Ext.data.operation.*', 'Ext.data.field.*', 'Ext.data.validator.Validator', 'Ext.data.schema.Schema', 'Ext.data.identifier.Generator', 'Ext.data.identifier.Sequential' ], uses: [ 'Ext.data.Validation' ], isEntity: true, isModel: true, validIdRe: null, erasing: false, observableType: 'record', constructor: function(data, session) { var me = this, cls = me.self, identifier = cls.identifier, Model = Ext.data.Model, modelIdentifier = Model.identifier, idProperty = me.idField.name, array, id, initializeFn, internalId, len, i, fields; me.data = me.data = data || (data = {}); me.session = session || null; me.internalId = internalId = modelIdentifier.generate(); var dataId = data[idProperty]; if (session && !session.isSession) { Ext.Error.raise('Bad Model constructor argument 2 - "session" is not a Session'); } if ((array = data) instanceof Array) { me.data = data = {}; fields = me.getFields(); len = Math.min(fields.length, array.length); for (i = 0; i < len; ++i) { data[fields[i].name] = array[i]; } } if (!(initializeFn = cls.initializeFn)) { cls.initializeFn = initializeFn = Model.makeInitializeFn(cls); } if (!initializeFn.$nullFn) { cls.initializeFn(me); } if (!(me.id = id = data[idProperty]) && id !== 0) { if (dataId) { Ext.Error.raise('The model ID configured in data ("' + dataId + '") has been rejected by the ' + me.fieldsMap[idProperty].type + ' field converter for the ' + idProperty + ' field'); } if (session) { identifier = session.getIdentifier(cls); id = identifier.generate(); } else if (modelIdentifier === identifier) { id = internalId; } else { id = identifier.generate(); } data[idProperty] = me.id = id; me.phantom = true; } if (session) { session.add(me); } if (me.init && Ext.isFunction(me.init)) { me.init(); } }, editing: false, dirty: false, session: null, dropped: false, erased: false, clientIdProperty: null, evented: false, phantom: false, idProperty: 'id', manyToMany: null, identifier: null, previousValues: undefined, proxy: undefined, schema: 'default', versionProperty: null, generation: 1, validationSeparator: null, convertOnSet: true, beginEdit: function() { var me = this, modified = me.modified, previousValues = me.previousValues; if (!me.editing) { me.editing = true; me.editMemento = { dirty: me.dirty, data: Ext.apply({}, me.data), generation: me.generation, modified: modified && Ext.apply({}, modified), previousValues: previousValues && Ext.apply({}, previousValues) }; } }, cancelEdit: function() { var me = this, editMemento = me.editMemento; if (editMemento) { me.editing = false; Ext.apply(me, editMemento); me.editMemento = null; } }, endEdit: function(silent, modifiedFieldNames) { var me = this, editMemento = me.editMemento; if (editMemento) { me.editing = false; me.editMemento = null; me.previousValues = editMemento.previousValues; if (!silent) { if (!modifiedFieldNames) { modifiedFieldNames = me.getModifiedFieldNames(editMemento.data); } if (me.dirty || (modifiedFieldNames && modifiedFieldNames.length)) { me.callJoined('afterEdit', [ modifiedFieldNames ]); } } } }, getField: function(name) { return this.self.getField(name); }, getFields: function() { return this.self.getFields(); }, getFieldsMap: function() { return this.fieldsMap; }, getIdProperty: function() { return this.idProperty; }, getId: function() { return this.id; }, getObservableId: function() { return this.internalId; }, setId: function(id) { this.set(this.idProperty, id); }, getPrevious: function(fieldName) { var previousValues = this.previousValues; return previousValues && previousValues[fieldName]; }, isModified: function(fieldName) { var modified = this.modified; return !!(modified && modified.hasOwnProperty(fieldName)); }, getModified: function(fieldName) { var out; if (this.isModified(fieldName)) { out = this.modified[fieldName]; } return out; }, get: function(fieldName) { return this.data[fieldName]; }, _singleProp: {}, _rejectOptions: { convert: false, silent: true }, set: function(fieldName, newValue, options) { var me = this, cls = me.self, data = me.data, modified = me.modified, prevVals = me.previousValues, session = me.session, single = Ext.isString(fieldName), opt = (single ? options : newValue), convertOnSet = opt ? opt.convert !== false : me.convertOnSet, fieldsMap = me.fieldsMap, silent = opt && opt.silent, commit = opt && opt.commit, updateRefs = !(opt && opt.refs === false) && session, dirty = !(opt && opt.dirty === false && !commit), modifiedFieldNames = null, currentValue, field, idChanged, key, name, oldId, comparator, dep, dependents, i, dirtyRank = 0, numFields, newId, rankedFields, reference, value, values; if (single) { values = me._singleProp; values[fieldName] = newValue; } else { values = fieldName; } if (!(rankedFields = cls.rankedFields)) { rankedFields = cls.rankFields(); } numFields = rankedFields.length; do { for (name in values) { value = values[name]; currentValue = data[name]; comparator = me; field = fieldsMap[name]; if (field) { if (convertOnSet && field.convert) { value = field.convert(value, me); } comparator = field; reference = field.reference; } else { reference = null; } if (comparator.isEqual(currentValue, value)) { continue; } data[name] = value; (modifiedFieldNames || (modifiedFieldNames = [])).push(name); (prevVals || (me.previousValues = prevVals = {}))[name] = currentValue; if (reference && reference.cls) { if (updateRefs) { session.updateReference(me, field, value, currentValue); } reference.onValueChange(me, session, value, currentValue); } i = (dependents = field && field.dependents) && dependents.length; while (i-- > 0) { (dep = dependents[i]).dirty = true; dirtyRank = dirtyRank ? Math.min(dirtyRank, dep.rank) : dep.rank; } if (!field || field.persist) { if (modified && modified.hasOwnProperty(name)) { if (!dirty || comparator.isEqual(modified[name], value)) { delete modified[name]; me.dirty = -1; } } else if (dirty) { if (!modified) { me.modified = modified = {}; } me.dirty = true; modified[name] = currentValue; } } if (name === me.idField.name) { idChanged = true; oldId = currentValue; newId = value; } } if (!dirtyRank) { break; } field = rankedFields[dirtyRank - 1]; field.dirty = false; if (single) { delete values[fieldName]; } else { values = me._singleProp; single = true; } fieldName = field.name; values[fieldName] = data[fieldName]; convertOnSet = true; for (; dirtyRank < numFields; ++dirtyRank) { if (rankedFields[dirtyRank].dirty) { break; } } if (dirtyRank < numFields) { ++dirtyRank; } else { dirtyRank = 0; } } while ( 1); if (me.dirty < 0) { me.dirty = false; for (key in modified) { if (modified.hasOwnProperty(key)) { me.dirty = true; break; } } } if (single) { delete values[fieldName]; } ++me.generation; if (idChanged) { me.id = newId; me.callJoined('onIdChanged', [ oldId, newId ]); } if (commit) { me.commit(silent, modifiedFieldNames); } else if (!silent && !me.editing && modifiedFieldNames) { me.callJoined('afterEdit', [ modifiedFieldNames ]); } return modifiedFieldNames; }, reject: function(silent) { var me = this, modified = me.modified; if (me.erased) { Ext.Error.raise('Cannot reject once a record has been erased.'); } if (modified) { me.set(modified, me._rejectOptions); } me.dropped = false; me.clearState(); if (!silent) { me.callJoined('afterReject'); } }, commit: function(silent, modifiedFieldNames) { var me = this, versionProperty = me.versionProperty, data = me.data, erased; me.clearState(); if (versionProperty && !me.phantom && !isNaN(data[versionProperty])) { ++data[versionProperty]; } me.phantom = false; if (me.dropped) { me.erased = erased = true; } if (!silent) { if (erased) { me.callJoined('afterErase'); } else { me.callJoined('afterCommit', [ modifiedFieldNames ]); } } }, clearState: function() { var me = this; me.dirty = me.editing = false; me.editMemento = me.modified = null; }, drop: function(cascade) { var me = this, associations = me.associations, session = me.session, roleName; if (me.erased || me.dropped) { return; } me.dropped = true; if (associations && cascade !== false) { for (roleName in associations) { associations[roleName].onDrop(me, session); } } me.callJoined('afterDrop'); if (me.phantom) { me.setErased(); } }, join: function(item) { var me = this, joined = me.joined; if (!joined) { joined = me.joined = [ item ]; } else if (!joined.length) { joined[0] = item; } else { Ext.Array.include(joined, item); } if (item.isStore && !me.store) { me.store = item; } }, unjoin: function(item) { var me = this, joined = me.joined, len = joined && joined.length, store = me.store, i; if (len === 1 && joined[0] === item) { joined.length = 0; } else if (len) { Ext.Array.remove(joined, item); } if (store === item) { store = null; if (joined) { for (i = 0 , len = joined.length; i < len; ++i) { item = joined[i]; if (item.isStore) { store = item; break; } } } me.store = store; } }, clone: function(session) { var me = this, modified = me.modified, ret = me.copy(me.id, session); if (modified) { ret.modified = Ext.apply({}, modified); } ret.dirty = me.dirty; ret.dropped = me.dropped; ret.phantom = me.phantom; return ret; }, copy: function(newId, session) { var me = this, data = Ext.apply({}, me.data), idProperty = me.idProperty, T = me.self; if (newId || newId === 0) { data[idProperty] = newId; } else if (newId === null) { delete data[idProperty]; } return new T(data, session); }, getProxy: function() { return this.self.getProxy(); }, getValidation: function(refresh) { var me = this, ret = me.validation; if (!ret) { me.validation = ret = new Ext.data.Validation(); ret.attach(me); } if (refresh === true || (refresh !== false && ret.syncGeneration !== me.generation)) { ret.refresh(refresh); } return ret; }, validate: function() { return new Ext.data.ErrorCollection().init(this); }, isValid: function() { return this.getValidation().isValid(); }, toUrl: function() { var pieces = this.$className.split('.'), name = pieces[pieces.length - 1].toLowerCase(); return name + '/' + this.getId(); }, erase: function(options) { var me = this; me.erasing = true; me.drop(); me.erasing = false; return me.save(options); }, setErased: function() { this.erased = true; this.callJoined('afterErase'); }, getChanges: function() { return this.getData(this._getChangesOptions); }, getCriticalFields: function() { var cls = this.self, ret = cls.criticalFields; if (!ret) { cls.rankFields(); ret = cls.criticalFields; } return ret; }, getAssociatedData: function(result, options) { var me = this, associations = me.associations, deep, i, item, items, itemData, length, record, role, roleName, opts, clear, associated; result = result || {}; me.$gathering = 1; if (options) { options = Ext.Object.chain(options); } for (roleName in associations) { role = associations[roleName]; item = role.getAssociatedItem(me); if (!item || item.$gathering) { continue; } if (item.isStore) { item.$gathering = 1; items = item.getData().items; length = items.length; itemData = []; for (i = 0; i < length; ++i) { record = items[i]; deep = !record.$gathering; record.$gathering = 1; if (options) { associated = options.associated; if (associated === undefined) { options.associated = deep; clear = true; } else if (!deep) { options.associated = false; clear = true; } opts = options; } else { opts = deep ? me._getAssociatedOptions : me._getNotAssociatedOptions; } itemData.push(record.getData(opts)); if (clear) { options.associated = associated; clear = false; } delete record.$gathering; } delete item.$gathering; } else { opts = options || me._getAssociatedOptions; if (options && options.associated === undefined) { opts.associated = true; } itemData = item.getData(opts); } result[roleName] = itemData; } delete me.$gathering; return result; }, getData: function(options) { var me = this, ret = {}, opts = (options === true) ? me._getAssociatedOptions : (options || ret), data = me.data, associated = opts.associated, changes = opts.changes, critical = changes && opts.critical, content = changes ? me.modified : data, fieldsMap = me.fieldsMap, persist = opts.persist, serialize = opts.serialize, criticalFields, field, n, name, value; if (content) { for (name in content) { value = data[name]; field = fieldsMap[name]; if (field) { if (persist && !field.persist) { continue; } if (serialize && field.serialize) { value = field.serialize(value, me); } } ret[name] = value; } } if (critical) { criticalFields = me.self.criticalFields || me.getCriticalFields(); for (n = criticalFields.length; n-- > 0; ) { name = (field = criticalFields[n]).name; if (!(name in ret)) { value = data[name]; if (serialize && field.serialize) { value = field.serialize(value, me); } ret[name] = value; } } } if (associated) { me.getAssociatedData(ret, opts); } return ret; }, getTransientFields: function() { var cls = this.self, ret = cls.transientFields; if (!ret) { cls.rankFields(); ret = cls.transientFields; } return ret; }, isLoading: function() { return !!this.loadOperation; }, abort: function() { var operation = this.loadOperation; if (operation) { operation.abort(); } }, load: function(options) { options = Ext.apply({}, options); var me = this, scope = options.scope || me, proxy = me.getProxy(), callback = options.callback, operation = me.loadOperation, id = me.getId(), extras; if (operation) { extras = operation.extraCalls; if (!extras) { extras = operation.extraCalls = []; } extras.push(options); return operation; } var doIdCheck = true; if (me.phantom) { doIdCheck = false; } options.id = id; options.recordCreator = function(data, type, readOptions) { var session = me.session; if (readOptions) { readOptions.recordCreator = session ? session.recordCreator : null; } me.set(data, me._commitOptions); if (doIdCheck && me.getId() !== id) { Ext.Error.raise('Invalid record id returned for ' + id + '@' + me.entityName); } return me; }; options.internalCallback = function(operation) { var success = operation.wasSuccessful() && operation.getRecords().length > 0, op = me.loadOperation, extras = op.extraCalls, successFailArgs = [ me, operation ], callbackArgs = [ me, operation, success ], i, len; me.loadOperation = null; if (success) { Ext.callback(options.success, scope, successFailArgs); } else { Ext.callback(options.failure, scope, successFailArgs); } Ext.callback(callback, scope, callbackArgs); if (extras) { for (i = 0 , len = extras.length; i < len; ++i) { options = extras[i]; if (success) { Ext.callback(options.success, scope, successFailArgs); } else { Ext.callback(options.failure, scope, successFailArgs); } Ext.callback(options.callback, scope, callbackArgs); } } me.callJoined('afterLoad'); }; delete options.callback; me.loadOperation = operation = proxy.createOperation('read', options); operation.execute(); return operation; }, save: function(options) { options = Ext.apply({}, options); var me = this, phantom = me.phantom, dropped = me.dropped, action = dropped ? 'destroy' : (phantom ? 'create' : 'update'), scope = options.scope || me, callback = options.callback, proxy = me.getProxy(), operation; options.records = [ me ]; options.internalCallback = function(operation) { var args = [ me, operation ], success = operation.wasSuccessful(); if (success) { Ext.callback(options.success, scope, args); } else { Ext.callback(options.failure, scope, args); } args.push(success); Ext.callback(callback, scope, args); }; delete options.callback; operation = proxy.createOperation(action, options); if (dropped && phantom) { operation.setResultSet(Ext.data.reader.Reader.prototype.nullResultSet); me.setErased(); operation.setSuccessful(true); } else { operation.execute(); } return operation; }, inheritableStatics: { addFields: function(newFields) { this.replaceFields(newFields); }, replaceFields: function(newFields, removeFields) { var me = this, proto = me.prototype, Field = Ext.data.field.Field, fields = me.fields, fieldsMap = me.fieldsMap, ordinals = me.fieldOrdinals, field, i, idField, len, name, ordinal; if (removeFields === true) { fields.length = 0; me.fieldsMap = fieldsMap = {}; me.fieldOrdinals = ordinals = {}; } else if (removeFields) { for (i = removeFields.length; i-- > 0; ) { name = removeFields[i]; if (name in ordinals) { delete ordinals[name]; delete fieldsMap[name]; } } for (i = 0 , len = fields.length; i < len; ++i) { name = (field = fields[i]).name; if (name in ordinals) { ordinals[name] = i; } else { fields.splice(i, 1); --i; --len; } } } for (i = 0 , len = newFields ? newFields.length : 0; i < len; i++) { name = (field = newFields[i]).name; if (!(name in ordinals)) { ordinals[name] = ordinal = fields.length; fields.push(field = Field.create(field)); fieldsMap[name] = field; field.ordinal = ordinal; field.definedBy = field.owner = this; } } me.idField = proto.idField = idField = fieldsMap[proto.idProperty]; idField.allowNull = idField.critical = idField.identifier = true; idField.defaultValue = null; me.initializeFn = me.rankedFields = me.transientFields = me.criticalFields = null; }, removeFields: function(removeFields) { this.replaceFields(null, removeFields); }, getIdFromData: function(data) { var T = this, idField = T.idField, id = idField.calculated ? (new T(data)).id : data[idField.name]; return id; }, createWithId: function(id, data, session) { var d = data, T = this; if (id || id === 0) { d = {}; if (data) { Ext.apply(d, data); } d[T.idField.name] = id; } return new T(d, session); }, getFields: function() { return this.fields; }, getFieldsMap: function() { return this.fieldsMap; }, getField: function(name) { return this.fieldsMap[name] || null; }, getProxy: function() { var me = this, proxy = me.proxy, defaults; if (!proxy) { proxy = me.proxyConfig; if (!proxy || !proxy.isProxy) { if (typeof proxy === 'string') { proxy = { type: proxy }; } defaults = me.schema.constructProxy(me); proxy = proxy ? Ext.merge(defaults, proxy) : defaults; } proxy = me.setProxy(proxy); } return proxy; }, setProxy: function(proxy) { var me = this, model; if (proxy) { if (!proxy.isProxy) { proxy = Ext.Factory.proxy(proxy); } else { model = proxy.getModel(); if (model && model !== me) { proxy = proxy.clone(); } } proxy.setModel(me); } return (me.prototype.proxy = me.proxy = proxy); }, load: function(id, options, session) { var data = {}, rec; data[this.prototype.idProperty] = id; rec = new this(data, session); rec.load(options); return rec; } }, deprecated: { 5: { methods: { hasId: null, markDirty: null, setDirty: null, eachStore: function(callback, scope) { var me = this, stores = me.stores, len = stores.length, i; for (i = 0; i < len; ++i) { callback.call(scope, stores[i]); } }, join: function(item) { var me = this, stores = me.stores, joined = me.joined; if (!joined) { joined = me.joined = [ item ]; } else { joined.push(item); } if (item.isStore) { me.store = me.store || item; if (!stores) { stores = me.stores = []; } stores.push(item); } }, unjoin: function(item) { var me = this, stores = me.stores, joined = me.joined; if (joined.length === 1) { joined.length = 0; } else { Ext.Array.remove(joined, item); } if (item.isStore) { Ext.Array.remove(stores, item); me.store = stores[0] || null; } } }, properties: { persistenceProperty: null }, inheritableStatics: { methods: { setFields: null } } } }, privates: { _commitOptions: { commit: true }, _getChangesOptions: { changes: true }, _getAssociatedOptions: { associated: true }, _getNotAssociatedOptions: { associated: false }, copyFrom: function(sourceRecord) { var me = this, fields = me.fields, fieldCount = fields.length, modifiedFieldNames = [], field, i = 0, myData, sourceData, idProperty = me.idProperty, name, value; if (sourceRecord) { myData = me.data; sourceData = sourceRecord.data; for (; i < fieldCount; i++) { field = fields[i]; name = field.name; if (name !== idProperty) { value = sourceData[name]; if (value !== undefined && !me.isEqual(myData[name], value)) { myData[name] = value; modifiedFieldNames.push(name); } } } if (me.phantom && !sourceRecord.phantom) { me.beginEdit(); me.setId(sourceRecord.getId()); me.endEdit(true); me.commit(true); } } return modifiedFieldNames; }, callJoined: function(funcName, args) { var me = this, joined = me.joined, session = me.session, i, len, fn, item; if (!joined && !session) { return; } if (args) { args.unshift(me); } else { args = [ me ]; } if (joined) { for (i = 0 , len = joined.length; i < len; ++i) { item = joined[i]; if (item && (fn = item[funcName])) { fn.apply(item, args); } } } fn = session && session[funcName]; if (fn) { fn.apply(session, args); } }, setSession: function(session) { if (session) { if (this.session) { Ext.Error.raise('This model already belongs to a session.'); } if (!this.id) { Ext.Error.raise('The model must have an id to participate in a session.'); } } this.session = session; if (session) { session.add(this); } }, getModifiedFieldNames: function(old) { var me = this, data = me.data, modified = [], oldData = old || me.editMemento.data, key; for (key in data) { if (data.hasOwnProperty(key)) { if (!me.isEqual(data[key], oldData[key], key)) { modified.push(key); } } } return modified; }, isEqual: function(lhs, rhs, field) { var f; if (field) { f = field.isField ? field : this.fieldsMap[field]; if (f) { return f.compare(lhs, rhs) === 0; } } if (lhs instanceof Date && rhs instanceof Date) { return lhs.getTime() === rhs.getTime(); } return lhs === rhs; }, statics: { EDIT: 'edit', REJECT: 'reject', COMMIT: 'commit', rankFields: function() { var cls = this, prototype = cls.prototype, fields = cls.fields, length = fields.length, rankedFields = [], criticalFields = [], transientFields = [], evilFields, field, i; cls.rankedFields = prototype.rankedFields = rankedFields; cls.criticalFields = prototype.criticalFields = criticalFields; cls.transientFields = prototype.transientFields = transientFields; for (i = 0; i < length; ++i) { field = fields[i]; if (field.critical) { criticalFields.push(field); } if (!field.persist) { transientFields.push(field); } if (field.evil) { (evilFields || (evilFields = [])).push(field); } else if (!field.depends) { rankedFields.push(field); field.rank = rankedFields.length; } } for (i = 0; i < length; ++i) { if (!(field = fields[i]).rank && !field.evil) { cls.topoAdd(field); } } if (evilFields) { for (i = 0 , length = evilFields.length; i < length; ++i) { rankedFields.push(field = evilFields[i]); field.rank = rankedFields.length; } } cls.topoStack = null; return rankedFields; }, topoAdd: function(field) { var cls = this, dep = field.depends, dependsLength = dep ? dep.length : 0, rankedFields = cls.rankedFields, i, targetField; var topoStack = cls.topoStack || (cls.topoStack = []); topoStack.push(field.name); if (field.rank === 0) { Ext.Error.raise(cls.$className + " has circular field dependencies: " + topoStack.join(" --> ")); } if (topoStack.length && field.evil) { Ext.Error.raise(cls.$className + ": Field " + topoStack[topoStack.length - 1] + " cannot depend on depends-less field " + field.name); } field.rank = 0; for (i = 0; i < dependsLength; ++i) { targetField = cls.fieldsMap[dep[i]]; if (!targetField) { Ext.Error.raise(cls.$className + ": Field " + field.name + " depends on undefined field " + dep[i]); } (targetField.dependents || (targetField.dependents = [])).push(field); if (!targetField.rank) { cls.topoAdd(targetField); } } rankedFields.push(field); field.rank = rankedFields.length; topoStack.pop(); }, initFields: function(data, cls, proto) { var Field = Ext.data.field.Field, fieldDefs = data.fields, fields = [], fieldOrdinals = {}, fieldsMap = {}, references = [], superFields = proto.fields, versionProperty = data.versionProperty || proto.versionProperty, idProperty = cls.idProperty, idField, field, i, length, name, ordinal, reference, superIdField, superIdFieldName, idDeclared; cls.fields = proto.fields = fields; cls.fieldOrdinals = proto.fieldOrdinals = fieldOrdinals; cls.fieldsMap = proto.fieldsMap = fieldsMap; cls.references = proto.references = references; if (superFields) { for (i = 0 , length = superFields.length; i < length; ++i) { fields[i] = field = Ext.Object.chain(superFields[i]); field.dependents = null; field.owner = cls; fieldOrdinals[name = field.name] = i; fieldsMap[name] = field; field.rank = null; if (field.generated) { superIdField = field; superIdFieldName = field.name; } } } if (fieldDefs) { delete data.fields; for (i = 0 , length = fieldDefs.length; i < length; ++i) { field = fieldDefs[i]; reference = field.reference; if (reference && typeof reference !== 'string') { reference = Ext.merge({}, reference); } field.$reference = reference; field = Field.create(fieldDefs[i]); name = field.name; ordinal = fieldOrdinals[name]; if (ordinal === undefined) { fieldOrdinals[name] = ordinal = fields.length; } fieldsMap[name] = field; fields[ordinal] = field; field.definedBy = field.owner = cls; field.ordinal = ordinal; if (name === idProperty) { idDeclared = field; } } } idField = fieldsMap[idProperty]; if (!idField) { if (superIdField && superIdField.generated) { ordinal = superIdField.ordinal; } else { ordinal = fields.length; } delete fieldsMap[superIdFieldName]; delete fieldOrdinals[superIdFieldName]; idField = new Field(idProperty); fields[ordinal] = idField; fieldOrdinals[idProperty] = ordinal; fieldsMap[idProperty] = idField; idField.definedBy = cls; idField.ordinal = ordinal; idField.generated = true; } else if (idDeclared && superIdField && superIdField.generated) { Ext.Array.remove(fields, superIdField); delete fieldsMap[superIdFieldName]; delete fieldOrdinals[superIdFieldName]; fieldsMap[idProperty] = idDeclared; for (i = 0 , length = fields.length; i < length; ++i) { field = fields[i]; fields.ordinal = i; fieldOrdinals[field.name] = i; } } idField.allowNull = idField.critical = idField.identifier = true; idField.defaultValue = null; cls.idField = proto.idField = idField; if (versionProperty) { field = fieldsMap[versionProperty]; if (!field) { ordinal = fields.length; field = new Field({ name: versionProperty, type: 'int' }); fields[ordinal] = field; fieldOrdinals[versionProperty] = ordinal; fieldsMap[versionProperty] = field; field.definedBy = cls; field.ordinal = ordinal; field.generated = true; } field.defaultValue = 1; field.critical = true; } }, initValidators: function(data, cls, proto) { var superValidators = proto.validators, validators, field, copy, validatorDefs, i, length, fieldValidator, name, validator, item; if (superValidators) { validators = {}; for (field in superValidators) { validators[field] = Ext.Array.clone(superValidators[field]); } } validatorDefs = data.validators || data.validations; if (data.validations) { delete data.validations; Ext.log.warn((cls.$className || 'Ext.data.Model') + ': validations has been deprecated. Please use validators instead.'); } if (validatorDefs) { delete data.validators; validators = validators || {}; if (Ext.isArray(validatorDefs)) { copy = {}; for (i = 0 , length = validatorDefs.length; i < length; ++i) { item = validatorDefs[i]; name = item.field; if (!copy[name]) { copy[name] = []; } item = item.fn || item; copy[name].push(item); } validatorDefs = copy; } for (name in validatorDefs) { fieldValidator = validatorDefs[name]; if (!Ext.isArray(fieldValidator)) { fieldValidator = [ fieldValidator ]; } validator = validators[name]; if (validators[name]) { Ext.Array.push(validator, fieldValidator); } else { validators[name] = fieldValidator; } } } if (validators) { for (name in validators) { field = cls.getField(name); if (field) { field.setModelValidators(validators[name]); } } } cls.validators = proto.validators = validators; }, initAssociations: function(schema, data, cls) { var associations = data.associations, belongsTo = data.belongsTo, hasMany = data.hasMany, hasOne = data.hasOne, matrices = data.manyToMany, i, length, assoc; if (data.belongsTo) { Ext.log.warn('Use of "belongsTo" is obsolete' + (cls.$className ? ' in ' + cls.$className : '')); delete data.belongsTo; } delete data.manyToMany; if (matrices) { schema.addMatrices(cls, matrices); } delete data.associations; delete data.belongsTo; delete data.hasMany; delete data.hasOne; if (associations) { associations = Ext.isArray(associations) ? associations : [ associations ]; for (i = 0 , length = associations.length; i < length; ++i) { assoc = associations[i]; switch (assoc.type) { case 'belongsTo': schema.addLegacyBelongsTo(cls, assoc); break; case 'hasMany': schema.addLegacyHasMany(cls, assoc); break; case 'hasOne': schema.addLegacyHasOne(cls, assoc); break; default: Ext.Error.raise('Invalid association type: "' + assoc.type + '"'); } } } if (belongsTo) { belongsTo = Ext.isArray(belongsTo) ? belongsTo : [ belongsTo ]; for (i = 0 , length = belongsTo.length; i < length; ++i) { schema.addLegacyBelongsTo(cls, belongsTo[i]); } } if (hasMany) { hasMany = Ext.isArray(hasMany) ? hasMany : [ hasMany ]; for (i = 0 , length = hasMany.length; i < length; ++i) { schema.addLegacyHasMany(cls, hasMany[i]); } } if (hasOne) { hasOne = Ext.isArray(hasOne) ? hasOne : [ hasOne ]; for (i = 0 , length = hasOne.length; i < length; ++i) { schema.addLegacyHasOne(cls, hasOne[i]); } } schema.afterLegacyAssociations(cls); }, initIdentifier: function(data, cls, proto) { var identifier = data.identifier || data.idgen, superIdent = proto.identifier || cls.schema._defaultIdentifier, generatorPrefix; if (data.idgen) { Ext.log.warn('Ext.data.Model: idgen has been deprecated. Please use identifier instead.'); } if (identifier) { delete data.identifier; delete data.idgen; identifier = Ext.Factory.dataIdentifier(identifier); } else if (superIdent) { if (superIdent.clone && !superIdent.getId()) { identifier = superIdent.clone(); } else if (superIdent.isGenerator) { identifier = superIdent; } else { identifier = Ext.Factory.dataIdentifier(superIdent); } } cls.identifier = proto.identifier = identifier; if (!identifier) { generatorPrefix = cls.entityName; if (!generatorPrefix) { generatorPrefix = Ext.id(null, 'extModel'); } cls.identifier = Ext.Factory.dataIdentifier({ type: 'sequential', prefix: generatorPrefix + '-' }); } }, findValidator: function(validators, name, cfg) { var type = cfg.type || cfg, field = validators[name], len, i, item; if (field) { for (i = 0 , len = field.length; i < len; ++i) { item = field[i]; if (item.type === type) { return item; } } } return null; }, makeInitializeFn: function(cls) { var code = [ 'var ' ], body = [ '\nreturn function (e) {\n var data = e.data, v;\n' ], fieldVars = [], work = 0, bc, ec, convert, expr, factory, field, fields, fs, hasDefValue, i, length; if (!(fields = cls.rankedFields)) { fields = cls.rankFields(); } for (i = 0 , length = fields.length; i < length; ++i) { field = fields[i]; fieldVars[i] = fs = 'f' + i; convert = field.convert; if (i) { code.push(', \n '); } code.push(fs, ' = $fields[' + i + ']'); code.push(' /* ', field.name, ' */'); if ((hasDefValue = (field.defaultValue !== undefined)) || convert) { expr = 'data["' + field.name + '"]'; ++work; bc = ec = ''; if (field.cloneDefaultValue) { bc = 'Ext.clone('; ec = ')'; } body.push('\n'); if (convert && hasDefValue) { body.push(' v = ', expr, ';\n' + ' if (v !== undefined) {\n' + ' v = ', fs, '.convert(v, e);\n' + ' }\n' + ' if (v === undefined) {\n' + ' v = ', bc, fs, '.defaultValue', ec, ';\n' + ' }\n' + ' ', expr, ' = v;'); } else if (convert) { body.push(' v = ', fs, '.convert(', expr, ',e);\n' + ' if (v !== undefined) {\n' + ' ', expr, ' = v;\n' + ' }\n'); } else if (hasDefValue) { body.push(' if (', expr, ' === undefined) {\n' + ' ', expr, ' = ', bc, fs, '.defaultValue', ec, ';\n' + ' }\n'); } } } if (!work) { return Ext.emptyFn; } code.push(';\n'); code.push.apply(code, body); code.push('}'); code = code.join(''); factory = new Function('$fields', 'Ext', code); return factory(fields, Ext); } } } }, function() { var Model = this, proto = Model.prototype, Schema = Ext.data.schema.Schema, defaultSchema; Model.proxyConfig = proto.proxy; delete proto.proxy; Model.fields = []; Model.fieldsMap = proto.fieldsMap = {}; Model.schema = proto.schema = Schema.get(proto.schema); proto.idField = new Ext.data.field.Field(proto.idProperty); Model.identifier = new Ext.data.identifier.Sequential(); Model.onExtended(function(cls, data) { var proto = cls.prototype, schemaName = data.schema, superCls = proto.superclass.self, schema, entityName, proxy; cls.idProperty = data.idProperty || proto.idProperty; if (schemaName) { delete data.schema; schema = Schema.get(schemaName); } else if (!(schema = proto.schema)) { schema = defaultSchema || (defaultSchema = Schema.get('default')); } cls.rankFields = Model.rankFields; cls.topoAdd = Model.topoAdd; proto.schema = cls.schema = schema; if (!(entityName = data.entityName)) { proto.entityName = entityName = schema.getEntityName(cls); if (!entityName) { if (data.associations) { Ext.Error.raise('Anonymous entities cannot specify "associations"'); } if (data.belongsTo) { Ext.Error.raise('Anonymous entities cannot specify "belongsTo"'); } if (data.hasMany) { Ext.Error.raise('Anonymous entities cannot specify "hasMany"'); } if (data.hasOne) { Ext.Error.raise('Anonymous entities cannot specify "hasOne"'); } if (data.matrices) { Ext.Error.raise('Anonymous entities cannot specify "manyToMany"'); } } } cls.entityName = entityName; cls.fieldExtractors = {}; Model.initIdentifier(data, cls, proto); Model.initFields(data, cls, proto); Model.initValidators(data, cls, proto); cls.fields.items = cls.fields; if (entityName) { schema.addEntity(cls); Model.initAssociations(schema, data, cls); } proxy = data.proxy; if (proxy) { delete data.proxy; } else if (superCls !== Model) { proxy = superCls.proxyConfig || superCls.proxy; } cls.proxyConfig = proxy; }); }); Ext.define('Ext.data.ResultSet', { isResultSet: true, $configPrefixed: false, config: { loaded: true, count: null, total: null, success: false, records: null, message: null }, constructor: function(config) { this.initConfig(config); }, getCount: function() { var count = this.callParent(), records; if (!count) { records = this.getRecords(); if (records) { count = records.length; } } return count; } }); Ext.define('Ext.data.reader.Reader', { alternateClassName: [ 'Ext.data.Reader', 'Ext.data.DataReader' ], requires: [ 'Ext.data.ResultSet', 'Ext.XTemplate', 'Ext.util.LruCache' ], mixins: [ 'Ext.mixin.Observable', 'Ext.mixin.Factoryable' ], alias: 'reader.base', factoryConfig: { defaultType: null }, config: { totalProperty: 'total', successProperty: 'success', rootProperty: '', messageProperty: '', typeProperty: '', implicitIncludes: true, readRecordsOnFailure: true, model: null, proxy: null, transform: null, keepRawData: true }, isReader: true, constructor: function(config) { if (config && config.hasOwnProperty('root')) { config = Ext.apply({}, config); config.rootProperty = config.root; delete config.root; Ext.log.error('Ext.data.reader.Reader: Using the deprecated "root" configuration. Use "rootProperty" instead.'); } var me = this; me.duringInit = 1; me.mixins.observable.constructor.call(me, config); --me.duringInit; me.buildExtractors(); }, applyModel: function(model) { return Ext.data.schema.Schema.lookupEntity(model); }, applyTransform: function(transform) { if (transform) { if (Ext.isFunction(transform)) { transform = { fn: transform }; } return transform.fn.bind(transform.scope || this); } return transform; }, forceBuildExtractors: function() { if (!this.duringInit) { this.buildExtractors(true); } }, updateTotalProperty: function() { this.forceBuildExtractors(); }, updateMessageProperty: function() { this.forceBuildExtractors(); }, updateSuccessProperty: function() { this.forceBuildExtractors(); }, read: function(response, readOptions) { var data, result; if (response) { if (response.responseText) { result = this.getResponseData(response); if (result && result.__$isError) { return new Ext.data.ResultSet({ total: 0, count: 0, records: [], success: false, message: result.msg }); } else { data = this.readRecords(result, readOptions); } } else { data = this.readRecords(response, readOptions); } } return data || this.nullResultSet; }, getNullResultSet: function() { return this.nullResultSet; }, createReadError: function(msg) { return { __$isError: true, msg: msg }; }, readRecords: function(data, readOptions, internalReadOptions) { var me = this, recordsOnly = internalReadOptions && internalReadOptions.recordsOnly, asRoot = internalReadOptions && internalReadOptions.asRoot, success, recordCount, records, root, total, value, message, transform; transform = this.getTransform(); if (transform) { data = transform(data); } me.buildExtractors(); if (me.getKeepRawData()) { me.rawData = data; } data = me.getData(data); success = true; recordCount = 0; records = []; if (me.getSuccessProperty()) { value = me.getSuccess(data); if (value === false || value === 'false') { success = false; } } if (me.getMessageProperty()) { message = me.getMessage(data); } if (success || me.getReadRecordsOnFailure()) { root = (asRoot || Ext.isArray(data)) ? data : me.getRoot(data); if (root) { total = root.length; } if (me.getTotalProperty()) { value = parseInt(me.getTotal(data), 10); if (!isNaN(value)) { total = value; } } if (root) { records = me.extractData(root, readOptions); recordCount = records.length; } } return recordsOnly ? records : new Ext.data.ResultSet({ total: total || recordCount, count: recordCount, records: records, success: success, message: message }); }, extractData: function(root, readOptions) { var me = this, entityType = readOptions && readOptions.model ? Ext.data.schema.Schema.lookupEntity(readOptions.model) : me.getModel(), schema = entityType.schema, includes = schema.hasAssociations(entityType) && me.getImplicitIncludes(), fieldExtractorInfo = me.getFieldExtractorInfo(entityType.fieldExtractors), length = root.length, records = new Array(length), typeProperty = me.getTypeProperty(), reader, node, nodeType, record, i; if (!length && Ext.isObject(root)) { root = [ root ]; length = 1; } for (i = 0; i < length; i++) { record = root[i]; if (!record.isModel) { node = record; if (typeProperty && (nodeType = me.getChildType(schema, node, typeProperty))) { reader = nodeType.getProxy().getReader(); record = reader.extractRecord(node, readOptions, nodeType, schema.hasAssociations(nodeType) && reader.getImplicitIncludes(), reader.getFieldExtractorInfo(nodeType.fieldExtractors)); } else { record = me.extractRecord(node, readOptions, entityType, includes, fieldExtractorInfo); } if (record.isModel && record.isNode) { record.raw = node; } } if (record.onLoad) { record.onLoad(); } records[i] = record; } return records; }, getChildType: function(schema, rawNode, typeProperty) { var namespace; switch (typeof typeProperty) { case 'string': return schema.getEntity(rawNode[typeProperty]); case 'object': namespace = typeProperty.namespace; return schema.getEntity((namespace ? namespace + '.' : '') + rawNode[typeProperty.name]); case 'function': return schema.getEntity(typeProperty(rawNode)); } }, extractRecordData: function(node, readOptions) { var entityType = readOptions && readOptions.model ? Ext.data.schema.Schema.lookupEntity(readOptions.model) : this.getModel(), fieldExtractorInfo = this.getFieldExtractorInfo(entityType.fieldExtractors); return this.extractRecord(node, readOptions, entityType, false, fieldExtractorInfo); }, extractRecord: function(node, readOptions, entityType, includes, fieldExtractorInfo) { var me = this, creatorFn = (readOptions && readOptions.recordCreator) || me.defaultRecordCreator, modelData, record; modelData = me.extractModelData(node, fieldExtractorInfo); record = creatorFn.call(me, modelData, entityType || me.getModel(), readOptions); if (includes && record.isModel) { me.readAssociated(record, node, readOptions); } return record; }, getFieldExtractorInfo: function(extractors) { if (!extractors) { return; } var type = this.$className, extractor = extractors[type]; if (extractor === undefined) { extractors[type] = extractor = this.buildFieldExtractors(); } return extractor; }, buildFieldExtractors: function() { var fields = this.getFields(), len = fields.length, buffer = [], extractors = [], out = null, cnt = 0, field, name, i, extractor; for (i = 0; i < len; ++i) { field = fields[i]; extractor = this.createFieldAccessor(field); if (extractor) { name = field.name; buffer.push('val = extractors[' + cnt + '](raw); if (val !== undefined) { data[\'' + name + '\'] = val; }'); extractors.push(extractor); ++cnt; } } if (buffer.length) { out = { extractors: extractors, fn: new Function('raw', 'data', 'extractors', 'var val;' + buffer.join('')) }; } return out; }, defaultRecordCreator: function(data, Model) { var record = new Model(data); record.phantom = false; return record; }, getModelData: function(raw) { return {}; }, extractModelData: function(raw, fieldExtractorInfo) { var data = this.getModelData(raw), fn; if (fieldExtractorInfo) { fn = fieldExtractorInfo.fn; fn(raw, data, fieldExtractorInfo.extractors); } return data; }, readAssociated: function(record, data, readOptions) { var roles = record.associations, key, role; for (key in roles) { if (roles.hasOwnProperty(key)) { role = roles[key]; if (role.cls) { role.read(record, data, this, readOptions); } } } }, getFields: function() { return this.getModel().fields; }, getData: Ext.identityFn, getRoot: Ext.identityFn, getResponseData: function(response) { Ext.Error.raise("getResponseData must be implemented in the Ext.data.reader.Reader subclass"); }, onMetaChange: function(meta) { var me = this, fields = meta.fields, model, newModel, clientIdProperty, proxy; me.metaData = meta; if (meta.root) { me.setRootProperty(meta.root); } if (meta.totalProperty) { me.setTotalProperty(meta.totalProperty); } if (meta.successProperty) { me.setSuccessProperty(meta.successProperty); } if (meta.messageProperty) { me.setMessageProperty(meta.messageProperty); } clientIdProperty = meta.clientIdProperty; if (fields) { newModel = Ext.define(null, { extend: 'Ext.data.Model', fields: fields, clientIdProperty: clientIdProperty }); me.setModel(newModel); proxy = me.getProxy(); if (proxy) { proxy.setModel(newModel); } } else if (clientIdProperty) { model = me.getModel(); if (model) { model.self.prototype.clientIdProperty = clientIdProperty; } } }, buildExtractors: function(force) { var me = this, totalProp, successProp, messageProp; if (force || !me.hasExtractors) { totalProp = me.getTotalProperty(); successProp = me.getSuccessProperty(); messageProp = me.getMessageProperty(); if (totalProp) { me.getTotal = me.getAccessor(totalProp); } if (successProp) { me.getSuccess = me.getAccessor(successProp); } if (messageProp) { me.getMessage = me.getAccessor(messageProp); } me.hasExtractors = true; return true; } }, getAccessor: function(prop) { var me = this, cache = me.extractorCache, ret, key; if (typeof prop === 'string') { key = me.getAccessorKey(prop); ret = cache.get(key); if (!ret) { ret = me.createAccessor(prop); cache.add(key, ret); } } else { ret = me.createAccessor(prop); } return ret; }, getAccessorKey: function(prop) { return this.$className + prop; }, createAccessor: Ext.emptyFn, createFieldAccessor: Ext.emptyFn, destroy: function() { var me = this; me.model = me.getTotal = me.getSuccess = me.getMessage = me.rawData = null; }, privates: { copyFrom: function(reader) { var me = this; reader.buildExtractors(); me.getTotal = reader.getTotal; me.getSuccess = reader.getSuccess; me.getMessage = reader.getMessage; ++me.duringInit; me.setConfig(reader.getConfig()); --me.duringInit; me.hasExtractors = true; } } }, function(Cls) { var proto = Cls.prototype; Ext.apply(proto, { nullResultSet: new Ext.data.ResultSet({ total: 0, count: 0, records: [], success: true, message: '' }) }); proto.extractorCache = new Ext.util.LruCache(); }); Ext.define('Ext.data.writer.Writer', { mixins: [ 'Ext.mixin.Factoryable' ], alias: 'writer.base', factoryConfig: { defaultType: null }, alternateClassName: [ 'Ext.data.DataWriter', 'Ext.data.Writer' ], config: { clientIdProperty: null, allDataOptions: { persist: true }, partialDataOptions: { changes: true, critical: true }, writeAllFields: false, dateFormat: null, nameProperty: 'name', writeRecordId: true, transform: null }, isWriter: true, constructor: function(config) { this.initConfig(config); }, applyTransform: function(transform) { if (transform) { if (Ext.isFunction(transform)) { transform = { fn: transform }; } return transform.fn.bind(transform.scope || this); } return transform; }, write: function(request) { var operation = request.getOperation(), records = operation.getRecords() || [], len = records.length, data = [], i; for (i = 0; i < len; i++) { data.push(this.getRecordData(records[i], operation)); } return this.writeRecords(request, data); }, writeRecords: Ext.emptyFn, getRecordData: function(record, operation) { var me = this, nameProperty = me.getNameProperty(), mapping = nameProperty !== 'name', idField = record.self.idField, key = idField[nameProperty] || idField.name, value = record.id, writeAll = me.getWriteAllFields(), ret, dateFormat, phantom, options, clientIdProperty, fieldsMap, data, field; if (idField.serialize) { value = idField.serialize(value); } if (!writeAll && operation && operation.isDestroyOperation) { ret = {}; ret[key] = value; } else { dateFormat = me.getDateFormat(); phantom = record.phantom; options = (phantom || writeAll) ? me.getAllDataOptions() : me.getPartialDataOptions(); clientIdProperty = phantom && me.getClientIdProperty(); fieldsMap = record.getFieldsMap(); options.serialize = false; data = record.getData(options); ret = mapping ? {} : data; if (clientIdProperty) { ret[clientIdProperty] = value; delete data[key]; } else if (!me.getWriteRecordId()) { delete data[key]; } for (key in data) { value = data[key]; if (!(field = fieldsMap[key])) { if (mapping) { ret[key] = value; } } else { if (field.isDateField && dateFormat && Ext.isDate(value)) { value = Ext.Date.format(value, dateFormat); } else if (field.serialize) { value = field.serialize(value, record); } if (mapping) { key = field[nameProperty] || key; } ret[key] = value; } } } return ret; } }); Ext.define('Ext.data.proxy.Proxy', { mixins: [ 'Ext.mixin.Factoryable', 'Ext.mixin.Observable' ], $configPrefixed: false, alias: 'proxy.proxy', alternateClassName: [ 'Ext.data.DataProxy', 'Ext.data.Proxy' ], requires: [ 'Ext.data.schema.Schema', 'Ext.data.reader.Reader', 'Ext.data.writer.Writer' ], uses: [ 'Ext.data.Batch', 'Ext.data.operation.*', 'Ext.data.Model' ], config: { batchOrder: 'create,update,destroy', batchActions: true, model: undefined, reader: { type: 'json' }, writer: { type: 'json' } }, isProxy: true, isSynchronous: false, constructor: function(config) { this.mixins.observable.constructor.call(this, config); this.pendingOperations = {}; }, applyModel: function(model) { return Ext.data.schema.Schema.lookupEntity(model); }, updateModel: function(model) { if (model) { var reader = this.getReader(); if (reader && !reader.getModel()) { reader.setModel(model); } } }, applyReader: function(reader) { return Ext.Factory.reader(reader); }, updateReader: function(reader) { if (reader) { var me = this, model = me.getModel(); if (!model) { model = reader.getModel(); if (model) { me.setModel(model); } } else { reader.setModel(model); } if (reader.onMetaChange) { reader.onMetaChange = Ext.Function.createSequence(reader.onMetaChange, me.onMetaChange, me); } } }, applyWriter: function(writer) { var reader = this.getReader(); writer = Ext.Factory.writer(writer); if (writer.getRecord && !writer.getRecord() && reader && reader.getRecord) { reader = reader.getRecord(); if (reader) { writer.setRecord(reader); } } return writer; }, abort: Ext.emptyFn, onMetaChange: function(meta) { this.fireEvent('metachange', this, meta); }, create: Ext.emptyFn, read: Ext.emptyFn, update: Ext.emptyFn, erase: Ext.emptyFn, batch: function(options, listeners) { var me = this, useBatch = me.getBatchActions(), batch, records, actions, aLen, action, a, r, rLen, record; if (options.operations === undefined) { options = { operations: options, listeners: listeners }; } if (options.batch) { if (Ext.isDefined(options.batch.runOperation)) { batch = Ext.applyIf(options.batch, { proxy: me, listeners: {} }); } } else { options.batch = { proxy: me, listeners: options.listeners || {} }; } if (!batch) { batch = new Ext.data.Batch(options.batch); } batch.on('complete', Ext.bind(me.onBatchComplete, me, [ options ], 0)); actions = me.getBatchOrder().split(','); aLen = actions.length; for (a = 0; a < aLen; a++) { action = actions[a]; records = options.operations[action]; if (records) { if (useBatch) { batch.add(me.createOperation(action, { records: records, params: options.params })); } else { rLen = records.length; for (r = 0; r < rLen; r++) { record = records[r]; batch.add(me.createOperation(action, { records: [ record ], params: options.params })); } } } } batch.start(); return batch; }, onBatchComplete: function(batchOptions, batch) { var scope = batchOptions.scope || this; if (batch.hasException()) { if (Ext.isFunction(batchOptions.failure)) { Ext.callback(batchOptions.failure, scope, [ batch, batchOptions ]); } } else if (Ext.isFunction(batchOptions.success)) { Ext.callback(batchOptions.success, scope, [ batch, batchOptions ]); } if (Ext.isFunction(batchOptions.callback)) { Ext.callback(batchOptions.callback, scope, [ batch, batchOptions ]); } }, createOperation: function(action, config) { var operation = Ext.createByAlias('data.operation.' + action, config); operation.setProxy(this); this.pendingOperations[operation._internalId] = operation; return operation; }, completeOperation: function(operation) { delete this.pendingOperations[operation._internalId]; }, clone: function() { return new this.self(this.getInitialConfig()); }, destroy: function() { var ops = this.pendingOperations, opId, op; for (opId in ops) { op = ops[opId]; if (op && op.isRunning()) { op.abort(); } } this.pendingOperations = null; } }); Ext.define('Ext.data.proxy.Client', { extend: 'Ext.data.proxy.Proxy', alternateClassName: 'Ext.data.ClientProxy', isSynchronous: true, 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.define('Ext.data.proxy.Memory', { extend: 'Ext.data.proxy.Client', alias: 'proxy.memory', alternateClassName: 'Ext.data.MemoryProxy', isMemoryProxy: true, config: { enablePaging: false, data: { $value: null, merge: function(newValue, currentValue, target, mixinClass) { if (Ext.isArray(newValue)) { return Ext.Array.clone(newValue); } else { return Ext.clone(newValue); } } } }, finishOperation: function(operation) { var i = 0, recs = operation.getRecords(), len = recs.length; for (i; i < len; i++) { recs[i].commit(); } operation.setSuccessful(true); }, create: function(operation) { this.finishOperation(operation); }, update: function(operation) { this.finishOperation(operation); }, erase: function(operation) { this.finishOperation(operation); }, read: function(operation) { var me = this, resultSet = me.getReader().read(me.getData()), records = resultSet.getRecords(), sorters = operation.getSorters(), grouper = operation.getGrouper(), filters = operation.getFilters(), start = operation.getStart(), limit = operation.getLimit(); if (operation.process(resultSet, null, null, false) !== false) { if (filters && filters.length) { resultSet.setRecords(records = Ext.Array.filter(records, Ext.util.Filter.createFilterFn(filters))); resultSet.setTotal(records.length); } if (grouper) { sorters = sorters ? sorters.concat(grouper) : sorters; } if (sorters && sorters.length) { resultSet.setRecords(records = Ext.Array.sort(records, Ext.util.Sortable.createComparator(sorters))); } if (me.getEnablePaging() && start !== undefined && limit !== undefined) { if (start >= resultSet.getTotal()) { resultSet.setConfig({ success: false, records: [], total: 0 }); } else { resultSet.setRecords(Ext.Array.slice(records, start, start + limit)); } } operation.setCompleted(); } }, clear: Ext.emptyFn }); Ext.define('Ext.data.ProxyStore', { extend: 'Ext.data.AbstractStore', requires: [ 'Ext.data.Model', 'Ext.data.proxy.Proxy', 'Ext.data.proxy.Memory', 'Ext.data.operation.*' ], config: { model: undefined, fields: null, proxy: undefined, autoLoad: undefined, autoSync: false, batchUpdateMode: 'operation', sortOnLoad: true, trackRemoved: true, autoLoadDelay: 1 }, onClassExtended: function(cls, data, hooks) { var model = data.model, onBeforeClassCreated; if (typeof model === 'string') { onBeforeClassCreated = hooks.onBeforeCreated; hooks.onBeforeCreated = function() { var me = this, args = arguments; Ext.require(model, function() { onBeforeClassCreated.apply(me, args); }); }; } }, implicitModel: false, blockLoadCounter: 0, loadsWhileBlocked: 0, autoSyncSuspended: 0, constructor: function(config) { var me = this; var configModel = me.model; me.removed = []; me.blockLoad(); me.callParent(arguments); me.unblockLoad(); if (!me.getModel() && me.useModelWarning !== false && me.getStoreId() !== 'ext-empty-store') { var logMsg = [ Ext.getClassName(me) || 'Store', ' created with no model.' ]; if (typeof configModel === 'string') { logMsg.push(" The name '", configModel, "'", ' does not correspond to a valid model.'); } Ext.log.warn(logMsg.join('')); } }, updateAutoLoad: function(autoLoad) { var me = this, task; me.getData(); if (autoLoad) { task = me.loadTask || (me.loadTask = new Ext.util.DelayedTask(null, null, null, null, false)); task.delay(me.autoLoadDelay, me.attemptLoad, me, Ext.isObject(autoLoad) ? [ autoLoad ] : undefined); } }, getTotalCount: function() { return this.totalCount || 0; }, applyFields: function(fields) { var me = this, model, proxy; if (fields) { me.implicitModel = true; me.setModel(model = Ext.define(null, { extend: 'Ext.data.Model', fields: fields, proxy: (proxy = me.getProxy()) })); if (proxy && !proxy.getModel()) { proxy.setModel(model); } } }, applyModel: function(model) { if (model) { model = Ext.data.schema.Schema.lookupEntity(model); } else { this.getFields(); model = this.getModel(); } return model; }, applyProxy: function(proxy) { var model = this.getModel(); if (proxy !== null) { if (proxy) { if (proxy.isProxy) { proxy.setModel(model); } else { if (Ext.isString(proxy)) { proxy = { type: proxy, model: model }; } else if (!proxy.model) { proxy = Ext.apply({ model: model }, proxy); } proxy = Ext.createByAlias('proxy.' + proxy.type, proxy); proxy.autoCreated = true; } } else if (model) { proxy = model.getProxy(); } if (!proxy) { proxy = Ext.createByAlias('proxy.memory'); proxy.autoCreated = true; } } return proxy; }, applyState: function(state) { var me = this, doLoad = me.getAutoLoad() || me.isLoaded(); me.blockLoad(); me.callParent([ state ]); me.unblockLoad(doLoad); }, updateProxy: function(proxy, oldProxy) { this.proxyListeners = Ext.destroy(this.proxyListeners); }, updateTrackRemoved: function(track) { this.cleanRemoved(); this.removed = track ? [] : null; }, onMetaChange: function(proxy, meta) { this.fireEvent('metachange', this, meta); }, create: function(data, options) { var me = this, Model = me.getModel(), instance = new Model(data), operation; options = Ext.apply({}, options); if (!options.records) { options.records = [ instance ]; } options.internalScope = me; options.internalCallback = me.onProxyWrite; operation = me.createOperation('create', options); return operation.execute(); }, read: function() { return this.load.apply(this, arguments); }, update: function(options) { var me = this, operation; options = Ext.apply({}, options); if (!options.records) { options.records = me.getUpdatedRecords(); } options.internalScope = me; options.internalCallback = me.onProxyWrite; operation = me.createOperation('update', options); return operation.execute(); }, onProxyWrite: function(operation) { var me = this, success = operation.wasSuccessful(), records = operation.getRecords(); switch (operation.getAction()) { case 'create': me.onCreateRecords(records, operation, success); break; case 'update': me.onUpdateRecords(records, operation, success); break; case 'destroy': me.onDestroyRecords(records, operation, success); break; } if (success) { me.fireEvent('write', me, operation); me.fireEvent('datachanged', me); } }, onCreateRecords: Ext.emptyFn, onUpdateRecords: Ext.emptyFn, onDestroyRecords: function(records, operation, success) { if (success) { this.cleanRemoved(); } }, erase: function(options) { var me = this, operation; options = Ext.apply({}, options); if (!options.records) { options.records = me.getRemovedRecords(); } options.internalScope = me; options.internalCallback = me.onProxyWrite; operation = me.createOperation('destroy', options); return operation.execute(); }, onBatchOperationComplete: function(batch, operation) { return this.onProxyWrite(operation); }, onBatchComplete: function(batch, operation) { var me = this, operations = batch.operations, length = operations.length, i; if (me.batchUpdateMode !== 'operation') { me.suspendEvents(); for (i = 0; i < length; i++) { me.onProxyWrite(operations[i]); } me.resumeEvents(); } me.isSyncing = false; me.fireEvent('datachanged', me); }, onBatchException: function(batch, operation) {}, filterNew: function(item) { return item.phantom === true && item.isValid(); }, getNewRecords: function() { return []; }, getUpdatedRecords: function() { return []; }, getModifiedRecords: function() { return [].concat(this.getNewRecords(), this.getUpdatedRecords()); }, filterUpdated: function(item) { return item.dirty === true && item.phantom !== true && item.isValid(); }, getRemovedRecords: function() { return this.removed; }, sync: function(options) { var me = this, operations = {}, toCreate = me.getNewRecords(), toUpdate = me.getUpdatedRecords(), toDestroy = me.getRemovedRecords(), needsSync = false; if (me.isSyncing) { Ext.log.warn('Sync called while a sync operation is in progress. Consider configuring autoSync as false.'); } me.needsSync = false; if (toCreate.length > 0) { operations.create = toCreate; needsSync = true; } if (toUpdate.length > 0) { operations.update = toUpdate; needsSync = true; } if (toDestroy.length > 0) { operations.destroy = toDestroy; needsSync = true; } if (needsSync && me.fireEvent('beforesync', operations) !== false) { me.isSyncing = true; options = options || {}; me.proxy.batch(Ext.apply(options, { operations: operations, listeners: me.getBatchListeners() })); } return me; }, getBatchListeners: function() { var me = this, listeners = { scope: me, exception: me.onBatchException, complete: me.onBatchComplete }; if (me.batchUpdateMode === 'operation') { listeners.operationcomplete = me.onBatchOperationComplete; } return listeners; }, save: function() { return this.sync.apply(this, arguments); }, load: function(options) { if (this.isLoadBlocked()) { return; } var me = this, operation = { internalScope: me, internalCallback: me.onProxyLoad }, filters, sorters; if (me.getRemoteFilter()) { filters = me.getFilters(false); if (filters && filters.getCount()) { operation.filters = filters.getRange(); } } if (me.getRemoteSort()) { sorters = me.getSorters(false); if (sorters && sorters.getCount()) { operation.sorters = sorters.getRange(); } me.fireEvent('beforesort', me, operation.sorters); } Ext.apply(operation, options); operation.scope = operation.scope || me; me.lastOptions = operation; operation = me.createOperation('read', operation); if (me.fireEvent('beforeload', me, operation) !== false) { me.onBeforeLoad(operation); me.loading = true; me.clearLoadTask(); operation.execute(); } return me; }, reload: function(options) { var o = Ext.apply({}, options, this.lastOptions); return this.load(o); }, onEndUpdate: function() { var me = this; if (me.needsSync && me.autoSync && !me.autoSyncSuspended) { me.sync(); } }, afterReject: function(record) { var me = this; if (me.contains(record)) { me.onUpdate(record, Ext.data.Model.REJECT, null); me.fireEvent('update', me, record, Ext.data.Model.REJECT, null); } }, afterCommit: function(record, modifiedFieldNames) { var me = this; if (!modifiedFieldNames) { modifiedFieldNames = null; } if (me.contains(record)) { me.onUpdate(record, Ext.data.Model.COMMIT, modifiedFieldNames); me.fireEvent('update', me, record, Ext.data.Model.COMMIT, modifiedFieldNames); } }, afterErase: function(record) { this.onErase(record); }, onErase: Ext.emptyFn, onUpdate: Ext.emptyFn, onDestroy: function() { var me = this, proxy = me.getProxy(); me.blockLoad(); me.clearData(); me.setProxy(null); if (proxy.autoCreated) { proxy.destroy(); } me.setModel(null); }, hasPendingLoad: function() { return !!this.loadTask || this.isLoading(); }, isLoading: function() { return !!this.loading; }, isLoaded: function() { return this.loadCount > 0; }, suspendAutoSync: function() { ++this.autoSyncSuspended; }, resumeAutoSync: function(syncNow) { var me = this; if (!me.autoSyncSuspended) { Ext.log.warn('Mismatched call to resumeAutoSync - auto synchronization is currently not suspended.'); } if (me.autoSyncSuspended && !--me.autoSyncSuspended) { if (syncNow) { me.sync(); } } }, removeAll: Ext.emptyFn, clearData: Ext.emptyFn, privates: { attemptLoad: function(options) { if (this.isLoadBlocked()) { ++this.loadsWhileBlocked; return; } this.load(options); }, blockLoad: function(value) { ++this.blockLoadCounter; }, clearLoadTask: function() { var loadTask = this.loadTask; if (loadTask) { loadTask.cancel(); this.loadTask = null; } }, cleanRemoved: function() { var removed = this.removed, len, i; if (removed) { for (i = 0 , len = removed.length; i < len; ++i) { removed[i].unjoin(this); } removed.length = 0; } }, createOperation: function(type, options) { var me = this, proxy = me.getProxy(), listeners; if (!me.proxyListeners) { listeners = { scope: me, destroyable: true, beginprocessresponse: me.beginUpdate, endprocessresponse: me.endUpdate }; if (!me.disableMetaChangeEvent) { listeners.metachange = me.onMetaChange; } me.proxyListeners = proxy.on(listeners); } return proxy.createOperation(type, options); }, isLoadBlocked: function() { return !!this.blockLoadCounter; }, loadsSynchronously: function() { return this.getProxy().isSynchronous; }, onBeforeLoad: Ext.privateFn, removeFromRemoved: function(record) { var removed = this.removed; if (removed) { Ext.Array.remove(removed, record); record.unjoin(this); } }, unblockLoad: function(doLoad) { var me = this, loadsWhileBlocked = me.loadsWhileBlocked; --me.blockLoadCounter; if (!me.blockLoadCounter) { me.loadsWhileBlocked = 0; if (doLoad && loadsWhileBlocked) { me.load(); } } } } }); Ext.define('Ext.data.LocalStore', { extend: 'Ext.Mixin', mixinConfig: { id: 'localstore' }, config: { extraKeys: null }, applyExtraKeys: function(extraKeys) { var indexName, data = this.getData(); data.setExtraKeys(extraKeys); extraKeys = data.getExtraKeys(); for (indexName in extraKeys) { this[indexName] = extraKeys[indexName]; } }, add: function(arg) { return this.insert(this.getCount(), arguments.length === 1 ? arg : arguments); }, constructDataCollection: function() { return new Ext.util.Collection({ rootProperty: 'data' }); }, createModel: function(record) { var session = this.getSession(), Model; if (!record.isModel) { Model = this.getModel(); record = new Model(record, session); } return record; }, createFiltersCollection: function() { return this.getData().getFilters(); }, createSortersCollection: function() { var sorters = this.getData().getSorters(); sorters.setSorterConfigure(this.addFieldTransform, this); return sorters; }, onCollectionSort: function() { this.onSorterEndUpdate(); }, onCollectionFilter: function() { this.onFilterEndUpdate(); }, notifySorterChange: function() { this.getData().onSorterChange(); }, forceLocalSort: function() { this.getData().onSortChange(); }, contains: function(record) { return this.indexOf(record) > -1; }, each: function(fn, scope) { var data = this.data.items, len = data.length, record, i; for (i = 0; i < len; ++i) { record = data[i]; if (fn.call(scope || record, record, i, len) === false) { break; } } }, collect: function(dataIndex, allowNull, bypassFilter) { var me = this, data = me.getData(); if (bypassFilter === true && data.filtered) { data = data.getSource(); } return data.collect(dataIndex, 'data', allowNull); }, getById: function(id) { var data = this.getData(); if (data.filtered) { data = data.getSource(); } return data.get(id) || null; }, getByInternalId: function(internalId) { var data = this.getData(), keyCfg; if (!this.hasInternalKeys) { keyCfg = { byInternalId: { property: 'internalId', rootProperty: '' } }; this.hasInternalKeys = true; } if (data.filtered) { if (keyCfg) { data.setExtraKeys(keyCfg); } data = data.getSource(); } if (keyCfg) { data.setExtraKeys(keyCfg); } return data.byInternalId.get(internalId) || null; }, indexOf: function(record) { return this.getData().indexOf(record); }, indexOfId: function(id) { return this.indexOf(this.getById(id)); }, insert: function(index, records) { var me = this, len, i; if (records) { if (!Ext.isIterable(records)) { records = [ records ]; } else { records = Ext.Array.clone(records); } len = records.length; } if (!len) { return []; } for (i = 0; i < len; ++i) { records[i] = me.createModel(records[i]); } me.getData().insert(index, records); return records; }, queryBy: function(fn, scope) { var data = this.getData(); return (data.getSource() || data).createFiltered(fn, scope); }, query: function(property, value, anyMatch, caseSensitive, exactMatch) { var data = this.getData(); return (data.getSource() || data).createFiltered(property, value, anyMatch, caseSensitive, exactMatch); }, first: function(grouped) { return this.getData().first(grouped) || null; }, last: function(grouped) { return this.getData().last(grouped) || null; }, sum: function(field, grouped) { var data = this.getData(); return (grouped && this.isGrouped()) ? data.sumByGroup(field) : data.sum(field); }, count: function(grouped) { var data = this.getData(); return (grouped && this.isGrouped()) ? data.countByGroup() : data.count(); }, min: function(field, grouped) { var data = this.getData(); return (grouped && this.isGrouped()) ? data.minByGroup(field) : data.min(field); }, max: function(field, grouped) { var data = this.getData(); return (grouped && this.isGrouped()) ? data.maxByGroup(field) : data.max(field); }, average: function(field, grouped) { var data = this.getData(); return (grouped && this.isGrouped()) ? data.averageByGroup(field) : data.average(field); }, aggregate: function(fn, scope, grouped, field) { var me = this, groups, len, out, group, i; if (grouped && me.isGrouped()) { groups = me.getGroups().items; len = groups.length; out = {}; for (i = 0; i < len; ++i) { group = groups[i]; out[group.getGroupKey()] = me.getAggregate(fn, scope || me, group.items, field); } return out; } else { return me.getAggregate(fn, scope, me.getData().items, field); } }, getAggregate: function(fn, scope, records, field) { var values = [], len = records.length, i; for (i = 0; i < len; ++i) { values[i] = records[i].get(field); } return fn.call(scope || this, records, values); }, addObserver: function(observer) { var observers = this.observers; if (!observers) { this.observers = observers = new Ext.util.Collection(); } observers.add(observer); }, removeObserver: function(observer) { var observers = this.observers; if (observers) { observers.remove(observer); } }, callObservers: function(action, args) { var observers = this.observers, len, items, i, methodName, item; if (observers) { items = observers.items; if (args) { args.unshift(this); } else { args = [ this ]; } for (i = 0 , len = items.length; i < len; ++i) { item = items[i]; methodName = 'onSource' + action; if (item[methodName]) { item[methodName].apply(item, args); } } } }, queryRecordsBy: function(fn, scope) { var data = this.getData(), matches = [], len, i, record; data = (data.getSource() || data).items; scope = scope || this; for (i = 0 , len = data.length; i < len; ++i) { record = data[i]; if (fn.call(scope, record) === true) { matches.push(record); } } return matches; }, queryRecords: function(field, value) { var data = this.getData(), matches = [], len, i, record; data = (data.getSource() || data).items; for (i = 0 , len = data.length; i < len; ++i) { record = data[i]; if (record.get(field) === value) { matches.push(record); } } return matches; }, privates: { isLast: function(record) { return record === this.last(); } } }); Ext.define('Ext.data.proxy.Server', { extend: 'Ext.data.proxy.Proxy', alias: 'proxy.server', alternateClassName: 'Ext.data.ServerProxy', uses: [ 'Ext.data.Request' ], isRemote: true, config: { url: '', pageParam: 'page', startParam: 'start', limitParam: 'limit', groupParam: 'group', groupDirectionParam: 'groupDir', sortParam: 'sort', filterParam: 'filter', directionParam: 'dir', idParam: 'id', simpleSortMode: false, simpleGroupMode: false, noCache: true, cacheString: "_dc", timeout: 30000, api: { create: undefined, read: undefined, update: undefined, destroy: undefined }, extraParams: {} }, create: function() { return this.doRequest.apply(this, arguments); }, read: function() { return this.doRequest.apply(this, arguments); }, update: function() { return this.doRequest.apply(this, arguments); }, erase: function() { return this.doRequest.apply(this, arguments); }, setExtraParam: function(name, value) { this.getExtraParams()[name] = value; }, buildRequest: function(operation) { var me = this, initialParams = Ext.apply({}, operation.getParams()), params = Ext.applyIf(initialParams, me.getExtraParams() || {}), request, operationId, idParam; Ext.applyIf(params, me.getParams(operation)); operationId = operation.getId(); idParam = me.getIdParam(); if (operationId !== undefined && params[idParam] === undefined) { params[idParam] = operationId; } request = new Ext.data.Request({ params: params, action: operation.getAction(), records: operation.getRecords(), url: operation.getUrl(), operation: operation, proxy: me }); request.setUrl(me.buildUrl(request)); operation.setRequest(request); return request; }, processResponse: function(success, operation, request, response) { var me = this, exception, reader, resultSet; me.fireEvent('beginprocessresponse', me, response, operation); if (success === true) { reader = me.getReader(); if (response.status === 204) { resultSet = reader.getNullResultSet(); } else { resultSet = reader.read(me.extractResponseData(response), { recordCreator: operation.getRecordCreator() }); } operation.process(resultSet, request, response); exception = !operation.wasSuccessful(); } else { me.setException(operation, response); exception = true; } if (exception) { me.fireEvent('exception', me, response, operation); } me.afterRequest(request, success); me.fireEvent('endprocessresponse', me, response, operation); }, setException: function(operation, response) { operation.setException({ status: response.status, statusText: response.statusText, response: response }); }, extractResponseData: Ext.identityFn, applyEncoding: function(value) { return Ext.encode(value); }, encodeSorters: function(sorters, preventArray) { var out = [], length = sorters.length, i; for (i = 0; i < length; i++) { out[i] = sorters[i].serialize(); } return this.applyEncoding(preventArray ? out[0] : out); }, encodeFilters: function(filters) { var out = [], length = filters.length, i, op; for (i = 0; i < length; i++) { out[i] = filters[i].serialize(); } return this.applyEncoding(out); }, getParams: function(operation) { if (!operation.isReadOperation) { return {}; } var me = this, params = {}, grouper = operation.getGrouper(), sorters = operation.getSorters(), filters = operation.getFilters(), page = operation.getPage(), start = operation.getStart(), limit = operation.getLimit(), simpleSortMode = me.getSimpleSortMode(), simpleGroupMode = me.getSimpleGroupMode(), pageParam = me.getPageParam(), startParam = me.getStartParam(), limitParam = me.getLimitParam(), groupParam = me.getGroupParam(), groupDirectionParam = me.getGroupDirectionParam(), sortParam = me.getSortParam(), filterParam = me.getFilterParam(), directionParam = me.getDirectionParam(), hasGroups, index; if (pageParam && page) { params[pageParam] = page; } if (startParam && (start || start === 0)) { params[startParam] = start; } if (limitParam && limit) { params[limitParam] = limit; } hasGroups = groupParam && grouper; if (hasGroups) { if (simpleGroupMode) { params[groupParam] = grouper.getProperty(); params[groupDirectionParam] = grouper.getDirection(); } else { params[groupParam] = me.encodeSorters([ grouper ], true); } } if (sortParam && sorters && sorters.length > 0) { if (simpleSortMode) { index = 0; if (sorters.length > 1 && hasGroups) { index = 1; } params[sortParam] = sorters[index].getProperty(); params[directionParam] = sorters[index].getDirection(); } 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.getNoCache()) { url = Ext.urlAppend(url, Ext.String.format("{0}={1}", me.getCacheString(), Ext.Date.now())); } return url; }, getUrl: function(request) { var url; if (request) { url = request.getUrl() || this.getApi()[request.getAction()]; } return url ? url : this.callParent(); }, doRequest: function(operation) { 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, destroy: function() { this.callParent(); Ext.destroy(this.getReader(), this.getWriter()); this.reader = this.writer = null; } }); Ext.define('Ext.data.proxy.Ajax', { requires: [ 'Ext.Ajax' ], extend: 'Ext.data.proxy.Server', alias: 'proxy.ajax', alternateClassName: [ 'Ext.data.HttpProxy', 'Ext.data.AjaxProxy' ], defaultActionMethods: { create: 'POST', read: 'GET', update: 'POST', destroy: 'POST' }, config: { binary: false, headers: undefined, paramsAsJson: false, withCredentials: false, useDefaultXhrHeader: true, username: null, password: null, actionMethods: { create: 'POST', read: 'GET', update: 'POST', destroy: 'POST' } }, doRequest: function(operation) { var me = this, writer = me.getWriter(), request = me.buildRequest(operation), method = me.getMethod(request), jsonData, params; if (writer && operation.allowWrite()) { request = writer.write(request); } request.setConfig({ binary: me.getBinary(), headers: me.getHeaders(), timeout: me.getTimeout(), scope: me, callback: me.createRequestCallback(request, operation), method: method, useDefaultXhrHeader: me.getUseDefaultXhrHeader(), disableCaching: false }); if (method.toUpperCase() !== 'GET' && me.getParamsAsJson()) { params = request.getParams(); if (params) { jsonData = request.getJsonData(); if (jsonData) { jsonData = Ext.Object.merge({}, jsonData, params); } else { jsonData = params; } request.setJsonData(jsonData); request.setParams(undefined); } } if (me.getWithCredentials()) { request.setWithCredentials(true); request.setUsername(me.getUsername()); request.setPassword(me.getPassword()); } return me.sendRequest(request); }, sendRequest: function(request) { request.setRawRequest(Ext.Ajax.request(request.getCurrentConfig())); this.lastRequest = request; return request; }, abort: function(request) { request = request || this.lastRequest; if (request) { Ext.Ajax.abort(request.getRawRequest()); } }, getMethod: function(request) { var actions = this.getActionMethods(), action = request.getAction(), method; if (actions) { method = actions[action]; } return method || this.defaultActionMethods[action]; }, createRequestCallback: function(request, operation) { var me = this; return function(options, success, response) { if (request === me.lastRequest) { me.lastRequest = null; } me.processResponse(success, operation, request, response); }; }, destroy: function() { this.lastRequest = null; this.callParent(); } }); Ext.define('Ext.data.reader.Json', { extend: 'Ext.data.reader.Reader', requires: [ 'Ext.JSON' ], alternateClassName: 'Ext.data.JsonReader', alias: 'reader.json', config: { record: null, metaProperty: 'metaData', useSimpleAccessors: false, preserveRawData: false }, updateRootProperty: function() { this.forceBuildExtractors(); }, updateMetaProperty: function() { this.forceBuildExtractors(); }, readRecords: function(data, readOptions, internalReadOptions) { var me = this, meta; if (me.getMeta) { meta = me.getMeta(data); if (meta) { me.onMetaChange(meta); } } else if (data.metaData) { me.onMetaChange(data.metaData); } return me.callParent([ data, readOptions, internalReadOptions ]); }, getResponseData: function(response) { try { return Ext.decode(response.responseText); } catch (ex) { Ext.Logger.warn('Unable to parse the JSON returned by the server'); return this.createReadError(ex.message); } }, buildExtractors: function() { var me = this, metaProp, rootProp; if (me.callParent(arguments)) { metaProp = me.getMetaProperty(); rootProp = me.getRootProperty(); if (rootProp) { me.getRoot = me.getAccessor(rootProp); } else { me.getRoot = Ext.identityFn; } if (metaProp) { me.getMeta = me.getAccessor(metaProp); } } }, extractData: function(root, readOptions) { var recordName = this.getRecord(), data = [], length, i; if (recordName) { length = root.length; if (!length && Ext.isObject(root)) { length = 1; root = [ root ]; } for (i = 0; i < length; i++) { data[i] = root[i][recordName]; } } else { data = root; } return this.callParent([ data, readOptions ]); }, getModelData: function(raw) { return this.getPreserveRawData() ? Ext.apply({}, raw) : raw; }, createAccessor: (function() { var re = /[\[\.]/; return function(expr) { var me = this, simple = me.getUseSimpleAccessors(), operatorIndex, result, current, parts, part, inExpr, isDot, isLeft, isRight, special, c, i, bracketed, len; if (!(expr || expr === 0)) { return; } if (typeof expr === 'function') { return expr; } if (!simple) { operatorIndex = String(expr).search(re); } if (simple === true || operatorIndex < 0) { result = function(raw) { return raw[expr]; }; } else { current = 'raw'; parts = []; part = ''; inExpr = 0; len = expr.length; for (i = 0; i <= len; ++i) { c = expr[i]; isDot = c === '.'; isLeft = c === '['; isRight = c === ']'; special = isDot || isLeft || isRight || !c; if (!special || inExpr > 1 || (inExpr && !isRight)) { part += c; } else if (special) { bracketed = false; if (isLeft) { ++inExpr; } else if (isRight) { --inExpr; bracketed = true; } if (part) { if (bracketed) { part = '[' + part + ']'; } else { part = '.' + part; } current += part; parts.push('' + current); part = ''; } } } result = parts.join(' && '); result = Ext.functionFactory('raw', 'return ' + result); } return result; }; }()), createFieldAccessor: function(field) { var me = this, mapping = field.mapping, hasMap = mapping || mapping === 0, map = hasMap ? mapping : field.name; if (hasMap) { if (typeof map === 'function') { return function(raw) { return field.mapping(raw, me); }; } else { return me.createAccessor(map); } } }, getAccessorKey: function(prop) { var simple = this.getUseSimpleAccessors() ? 'simple' : ''; return this.$className + simple + prop; }, privates: { copyFrom: function(reader) { this.callParent([ reader ]); this.getRoot = reader.getRoot; } } }); Ext.define('Ext.data.writer.Json', { extend: 'Ext.data.writer.Writer', alternateClassName: 'Ext.data.JsonWriter', alias: 'writer.json', config: { rootProperty: undefined, encode: false, allowSingle: true, expandData: false }, constructor: function(config) { if (config && config.hasOwnProperty('root')) { config = Ext.apply({}, config); config.rootProperty = config.root; delete config.root; Ext.log.warn('Ext.data.writer.Json: Using the deprecated "root" configuration. Use "rootProperty" instead.'); } this.callParent([ config ]); }, getExpandedData: function(data) { var dataLength = data.length, i = 0, item, prop, nameParts, j, tempObj, toObject = function(name, value) { var o = {}; o[name] = value; return o; }; for (; i < dataLength; i++) { item = data[i]; for (prop in item) { if (item.hasOwnProperty(prop)) { nameParts = prop.split('.'); j = nameParts.length - 1; if (j > 0) { tempObj = item[prop]; for (; j > 0; j--) { tempObj = toObject(nameParts[j], tempObj); } item[nameParts[0]] = item[nameParts[0]] || {}; Ext.Object.merge(item[nameParts[0]], tempObj); delete item[prop]; } } } } return data; }, writeRecords: function(request, data) { var me = this, root = me.getRootProperty(), json, single, transform; if (me.getExpandData()) { data = me.getExpandedData(data); } if (me.getAllowSingle() && data.length === 1) { data = data[0]; single = true; } transform = this.getTransform(); if (transform) { data = transform(data, request); } if (me.getEncode()) { if (root) { request.setParam(root, Ext.encode(data)); } else { Ext.Error.raise('Must specify a root when using encode'); } } else if (single || (data && data.length)) { json = request.getJsonData() || {}; if (root) { json[root] = data; } else { json = data; } request.setJsonData(json); } return request; } }); Ext.define('Ext.util.Group', { extend: 'Ext.util.Collection', config: { groupKey: null }, $endUpdatePriority: 2001 }); Ext.define('Ext.util.SorterCollection', { extend: 'Ext.util.Collection', requires: [ 'Ext.util.Sorter' ], isSorterCollection: true, $sortable: null, sortFn: null, config: { sorterOptionsFn: null, sorterOptionsScope: null }, constructor: function(config) { var me = this; me.sortFn = Ext.util.Sorter.createComparator(me); me.callParent([ config ]); me.setDecoder(me.decodeSorter); }, addSort: function(property, direction, mode) { var me = this, count, index, limit, options, primary, sorter, sorters; if (!property) { me.beginUpdate(); me.endUpdate(); } else { options = me.getOptions(); if (property instanceof Array) { sorters = property; mode = direction; direction = null; } else if (Ext.isString(property)) { if (!(sorter = me.get(property))) { sorters = [ { property: property, direction: direction || options.getDefaultSortDirection() } ]; } else { sorters = [ sorter ]; } } else if (Ext.isFunction(property)) { sorters = [ { sorterFn: property, direction: direction || options.getDefaultSortDirection() } ]; } else { if (!Ext.isObject(property)) { Ext.Error.raise('Invalid sort descriptor: ' + property); } sorters = [ property ]; mode = direction; direction = null; } if (mode && !me._sortModes[mode]) { Ext.Error.raise('Sort mode should be "multi", "append", "prepend" or "replace", not "' + mode + '"'); } mode = me._sortModes[mode || 'replace']; primary = me.getAt(0); count = me.length; index = mode.append ? count : 0; me.beginUpdate(); me.splice(index, mode.replace ? count : 0, sorters); if (mode.multi) { count = me.length; limit = options.getMultiSortLimit(); if (count > limit) { me.removeAt(limit, count); } } if (sorter && direction) { sorter.setDirection(direction); } else if (index === 0 && primary && primary === me.getAt(0)) { primary.toggle(); } me.endUpdate(); } }, getSortFn: function() { return this.sortFn; }, getByProperty: function(prop) { var items = this.items, len = items.length, i, item; for (i = 0; i < len; ++i) { item = items[i]; if (item.getProperty() === prop) { return item; } } return null; }, _sortModes: { append: { append: 1 }, multi: { multi: 1 }, prepend: { prepend: 1 }, replace: { replace: 1 } }, decodeSorter: function(sorter, xclass) { var me = this, options = me.getOptions(), root = options.getRootProperty(), sorterOptionsFn = me.getSorterOptionsFn(), currentSorter, sorterConfig, type; if (sorter.isSorter) { if (!sorter.getRoot()) { sorter.setRoot(root); } } else { sorterConfig = { direction: options.getDefaultSortDirection(), root: root }; type = typeof sorter; if (type === 'string') { currentSorter = me.get(sorter); if (currentSorter) { return currentSorter; } sorterConfig.property = sorter; } else if (type === 'function') { sorterConfig.sorterFn = sorter; } else { if (!Ext.isObject(sorter)) { Ext.Error.raise('Invalid sorter specified: ' + sorter); } sorterConfig = Ext.apply(sorterConfig, sorter); if (sorterConfig.fn) { sorterConfig.sorterFn = sorterConfig.fn; delete sorterConfig.fn; } } sorter = Ext.create(xclass || 'Ext.util.Sorter', sorterConfig); } if (sorterOptionsFn) { sorterOptionsFn.call(me.getSorterOptionsScope() || me, sorter); } return sorter; }, setSorterConfigure: function(fn, scope) { this.setSorterOptionsFn(fn); this.setSorterOptionsScope(scope); }, decodeRemoveItems: function(args, index) { var me = this, ret = (index === undefined) ? args : args[index]; if (!ret || !ret.$cloned) { if (args.length > index + 1 || !Ext.isIterable(ret)) { ret = Ext.Array.slice(args, index); } var currentSorters = me.items, ln = ret.length, remove = [], i, item, n, sorter, type; for (i = 0; i < ln; i++) { sorter = ret[i]; if (sorter && sorter.isSorter) { remove.push(sorter); } else { type = typeof sorter; if (type === 'string') { sorter = me.get(sorter); if (sorter) { remove.push(sorter); } } else if (type === 'function') { for (n = currentSorters.length; n-- > 0; ) { item = currentSorters[n]; if (item.getSorterFn() === sorter) { remove.push(item); } } } else { Ext.Error.raise('Invalid sorter specification: ' + sorter); } } } ret = remove; ret.$cloned = true; } return ret; }, getOptions: function() { return this.$sortable || this; } }); Ext.define('Ext.util.FilterCollection', { extend: 'Ext.util.Collection', requires: [ 'Ext.util.Filter' ], isFilterCollection: true, $filterable: null, filterFn: null, constructor: function(config) { var me = this; me.filterFn = Ext.util.Filter.createFilterFn(me); me.callParent([ config ]); me.setDecoder(me.decodeFilter); }, filterData: function(data) { return this.filtered ? Ext.Array.filter(data, this.filterFn) : data; }, getFilterFn: function() { return this.filterFn; }, isItemFiltered: function(item) { return !this.filterFn(item); }, decodeFilter: function(filter) { var options = this.getOptions(), filterRoot = options.getRootProperty(), filterConfig; if (filter.isFilter) { if (!filter.getRoot()) { filter.setRoot(filterRoot); } } else { filterConfig = { root: filterRoot }; if (Ext.isFunction(filter)) { filterConfig.filterFn = filter; } else { if (!Ext.isObject(filter)) { Ext.Error.raise('Invalid filter specified: ' + filter); } filterConfig = Ext.apply(filterConfig, filter); if (filterConfig.fn) { filterConfig.filterFn = filterConfig.fn; delete filterConfig.fn; } if (Ext.util.Filter.isInvalid(filterConfig)) { return false; } } filter = new Ext.util.Filter(filterConfig); } return filter; }, decodeRemoveItems: function(args, index) { var me = this, ret = (index === undefined) ? args : args[index]; if (!ret.$cloned) { if (args.length > index + 1 || !Ext.isIterable(ret)) { ret = Ext.Array.slice(args, index); } var currentFilters = me.items, ln = ret.length, remove = [], filter, i, isFunction, isProp, isString, item, match, n, type; for (i = 0; i < ln; i++) { filter = ret[i]; if (filter && filter.isFilter) { remove.push(filter); } else { type = typeof filter; isFunction = type === 'function'; isProp = filter.property !== undefined && filter.value !== undefined; isString = type === 'string'; if (!isFunction && !isProp && !isString) { Ext.Error.raise('Invalid filter specification: ' + filter); } for (n = currentFilters.length; n-- > 0; ) { item = currentFilters[n]; match = false; if (isString) { match = item.getProperty() === filter; } else if (isFunction) { match = item.getFilterFn() === filter; } else if (isProp) { match = item.getProperty() === filter.property && item.getValue() === filter.value; } if (match) { remove.push(item); } } } } ret = remove; ret.$cloned = true; } return ret; }, getOptions: function() { return this.$filterable || this; } }); Ext.define('Ext.util.GroupCollection', { extend: 'Ext.util.Collection', requires: [ 'Ext.util.Group', 'Ext.util.SorterCollection', 'Ext.util.FilterCollection' ], isGroupCollection: true, config: { grouper: null, itemRoot: null }, observerPriority: -100, onCollectionAdd: function(source, details) { this.addItemsToGroups(source, details.items); }, onCollectionBeforeItemChange: function(source, details) { this.changeDetails = details; }, onCollectionBeginUpdate: function() { this.beginUpdate(); }, onCollectionEndUpdate: function() { this.endUpdate(); }, onCollectionItemChange: function(source, details) { var item = details.item; if (!details.indexChanged) { this.syncItemGrouping(source, item, source.getKey(item), details.oldKey, details.oldIndex); } this.changeDetails = null; }, onCollectionRefresh: function(source) { this.removeAll(); this.addItemsToGroups(source, source.items); }, onCollectionRemove: function(source, details) { var me = this, changeDetails = me.changeDetails, entries, entry, group, i, n, removeGroups, item; if (changeDetails) { item = changeDetails.item; group = me.findGroupForItem(item); entries = []; if (group) { entries.push({ group: group, items: [ item ] }); } } else { entries = me.groupItems(source, details.items, false); } for (i = 0 , n = entries.length; i < n; ++i) { group = (entry = entries[i]).group; if (group) { group.remove(entry.items); if (!group.length) { (removeGroups || (removeGroups = [])).push(group); } } } if (removeGroups) { me.remove(removeGroups); } }, onCollectionSort: function(source) { var me = this, sorters = source.getSorters(false), items, length, i, group; if (sorters) { items = me.items; length = me.length; for (i = 0; i < length; ++i) { group = items[i]; if (group.getSorters() !== sorters) { group.setSorters(sorters); } } } }, onCollectionUpdateKey: function(source, details) { var index = details.index, item = details.item; if (!details.indexChanged) { index = source.indexOf(item); this.syncItemGrouping(source, item, details.newKey, details.oldKey, index); } }, addItemsToGroups: function(source, items) { this.groupItems(source, items, true); }, groupItems: function(source, items, adding) { var me = this, byGroup = {}, entries = [], grouper = source.getGrouper(), groupKeys = me.itemGroupKeys, entry, group, groupKey, i, item, itemKey, len, newGroups; for (i = 0 , len = items.length; i < len; ++i) { groupKey = grouper.getGroupString(item = items[i]); itemKey = source.getKey(item); if (adding) { (groupKeys || (me.itemGroupKeys = groupKeys = {}))[itemKey] = groupKey; } else if (groupKeys) { delete groupKeys[itemKey]; } if (!(entry = byGroup[groupKey])) { if (!(group = me.getByKey(groupKey)) && adding) { (newGroups || (newGroups = [])).push(group = me.createGroup(source, groupKey)); } entries.push(byGroup[groupKey] = entry = { group: group, items: [] }); } entry.items.push(item); } for (i = 0 , len = entries.length; i < len; ++i) { entry = entries[i]; entry.group.add(entry.items); } if (newGroups) { me.add(newGroups); } return entries; }, syncItemGrouping: function(source, item, itemKey, oldKey, itemIndex) { var me = this, itemGroupKeys = me.itemGroupKeys || (me.itemGroupKeys = {}), grouper = source.getGrouper(), groupKey = grouper.getGroupString(item), removeGroups = 0, index = -1, addGroups, group, oldGroup, oldGroupKey, firstIndex; if (oldKey) { oldGroupKey = itemGroupKeys[oldKey]; delete itemGroupKeys[oldKey]; } else { oldGroupKey = itemGroupKeys[itemKey]; } itemGroupKeys[itemKey] = groupKey; if (!(group = me.get(groupKey))) { group = me.createGroup(source, groupKey); addGroups = [ group ]; } if (group.get(itemKey) !== item) { if (group.getCount() > 0 && source.getSorters().getCount() === 0) { firstIndex = source.indexOf(group.items[0]); if (itemIndex < firstIndex) { index = 0; } else { index = itemIndex - firstIndex; } } if (index === -1) { group.add(item); } else { group.insert(index, item); } } else { group.itemChanged(item); } if (groupKey !== oldGroupKey && (oldGroupKey === 0 || oldGroupKey)) { oldGroup = me.get(oldGroupKey); if (oldGroup) { oldGroup.remove(item); if (!oldGroup.length) { removeGroups = [ oldGroup ]; } } } if (addGroups) { me.splice(0, removeGroups, addGroups); } else if (removeGroups) { me.splice(0, removeGroups); } }, createGroup: function(source, key) { var group = new Ext.util.Group({ groupKey: key, rootProperty: this.getItemRoot(), sorters: source.getSorters() }); return group; }, getKey: function(item) { return item.getGroupKey(); }, createSortFn: function() { var me = this, grouper = me.getGrouper(), sorterFn = me.getSorters().getSortFn(); if (!grouper) { return sorterFn; } return function(lhs, rhs) { return grouper.sort(lhs.items[0], rhs.items[0]) || sorterFn(lhs, rhs); }; }, updateGrouper: function(grouper) { var me = this; me.grouped = !!(grouper && me.$groupable.getAutoGroup()); me.onSorterChange(); me.onEndUpdateSorters(me.getSorters()); }, destroy: function() { this.$groupable = null; this.callParent(); }, privates: { findGroupForItem: function(item) { var items = this.items, len = items.length, i, group; for (i = 0; i < len; ++i) { group = items[i]; if (group.contains(item)) { return group; } } } } }); Ext.define('Ext.data.Store', { extend: 'Ext.data.ProxyStore', alias: 'store.store', mixins: [ 'Ext.data.LocalStore' ], requires: [ 'Ext.data.Model', 'Ext.data.proxy.Ajax', 'Ext.data.reader.Json', 'Ext.data.writer.Json', 'Ext.util.GroupCollection', 'Ext.util.DelayedTask' ], uses: [ 'Ext.data.StoreManager', 'Ext.util.Grouper' ], config: { data: 0, clearRemovedOnLoad: true, clearOnPageLoad: true, associatedEntity: null, role: null, session: null }, addRecordsOptions: { addRecords: true }, loadCount: 0, complete: false, moveMapCount: 0, constructor: function(config) { var me = this, data; if (config) { if (config.buffered) { if (this.self !== Ext.data.Store) { Ext.Error.raise('buffered config not supported on derived Store classes. ' + 'Please derive from Ext.data.BufferedStore.'); } return new Ext.data.BufferedStore(config); } if (config.remoteGroup) { Ext.log.warn('Ext.data.Store: remoteGroup has been removed. Use remoteSort instead.'); } } me.callParent([ config ]); me.getData().addObserver(me); data = me.inlineData; if (data) { delete me.inlineData; me.loadInlineData(data); } }, onCollectionBeginUpdate: function() { this.beginUpdate(); }, onCollectionEndUpdate: function() { this.endUpdate(); }, applyData: function(data, dataCollection) { var me = this; me.getFields(); me.getModel(); if (data && data.isCollection) { dataCollection = data; } else { if (!dataCollection) { dataCollection = me.constructDataCollection(); } if (data) { if (me.isInitializing) { me.inlineData = data; } else { me.loadData(data); } } } return dataCollection; }, loadInlineData: function(data) { var me = this, proxy = me.getProxy(), blocked; if (proxy && proxy.isMemoryProxy) { proxy.setData(data); blocked = me.blockLoadCounter; me.blockLoadCounter = 0; me.suspendEvents(); me.read(); me.resumeEvents(); me.blockLoadCounter = blocked; } else { me.removeAll(true); me.suspendEvents(); me.loadData(data); me.resumeEvents(); } }, onCollectionAdd: function(collection, info) { this.onCollectionAddItems(collection, info.items, info); }, onCollectionFilterAdd: function(collection, items) { this.onCollectionAddItems(collection, items); }, onCollectionAddItems: function(collection, records, info) { var me = this, len = records.length, lastChunk = info ? !info.next : false, removed = me.getRemovedRecords(), ignoreAdd = me.ignoreCollectionAdd, session = me.getSession(), replaced = info && info.replaced, i, sync, record, replacedItems; for (i = 0; i < len; ++i) { record = records[i]; if (session) { session.adopt(record); } if (!ignoreAdd) { record.join(me); if (removed && removed.length) { Ext.Array.remove(removed, record); } sync = sync || record.phantom || record.dirty; } } if (ignoreAdd) { return; } if (replaced) { replacedItems = []; do { Ext.Array.push(replacedItems, replaced.items); replaced = replaced.next; } while (replaced); me.setMoving(replacedItems, true); } if (info) { me.fireEvent('add', me, records, info.at); if (lastChunk) { me.fireEvent('datachanged', me); } } if (replacedItems) { me.setMoving(replacedItems, false); } me.needsSync = me.needsSync || sync; }, onCollectionFilteredItemChange: function() { this.onCollectionItemChange.apply(this, arguments); }, onCollectionItemChange: function(collection, info) { var me = this, record = info.item, modifiedFieldNames = info.modified || null, type = info.meta; if (me.fireChangeEvent(record)) { me.onUpdate(record, type, modifiedFieldNames, info); me.fireEvent('update', me, record, type, modifiedFieldNames, info); } }, fireChangeEvent: function(record) { var data = this.getData(); data = data.getSource() || data; return data.contains(record); }, afterChange: function(record, modifiedFieldNames, type) { this.getData().itemChanged(record, modifiedFieldNames || null, undefined, type); }, afterCommit: function(record, modifiedFieldNames) { this.afterChange(record, modifiedFieldNames, Ext.data.Model.COMMIT); }, afterEdit: function(record, modifiedFieldNames) { this.needsSync = this.needsSync || record.dirty; this.afterChange(record, modifiedFieldNames, Ext.data.Model.EDIT); }, afterReject: function(record) { this.afterChange(record, null, Ext.data.Model.REJECT); }, afterDrop: function(record) { this.getData().remove(record); }, afterErase: function(record) { this.removeFromRemoved(record); }, addSorted: function(record) { var me = this, remote = me.getRemoteSort(), data = me.getData(), index; if (remote) { data.setSorters(me.getSorters()); } index = data.findInsertionIndex(record); if (remote) { data.setSorters(null); } return me.insert(index, record); }, remove: function(records, isMove, silent) { var me = this, data = me.getData(), len, i, toRemove, record; if (records) { if (records.isModel) { if (me.indexOf(records) > -1) { toRemove = [ records ]; len = 1; } else { len = 0; } } else { toRemove = []; for (i = 0 , len = records.length; i < len; ++i) { record = records[i]; if (record && record.isEntity) { if (!data.contains(record)) { continue; } } else if (!(record = data.getAt(record))) { continue; } toRemove.push(record); } len = toRemove.length; } } if (!len) { return []; } me.removeIsMove = isMove === true; me.removeIsSilent = silent; data.remove(toRemove); me.removeIsSilent = false; return toRemove; }, onCollectionRemove: function(collection, info) { var me = this, removed = me.removed, records = info.items, len = records.length, index = info.at, isMove = me.removeIsMove, silent = me.removeIsSilent, lastChunk = !info.next, replacement = info.replacement, data = me.getData(), i, record; if (me.ignoreCollectionRemove) { return; } data = data.getSource() || data; if (replacement) { me.setMoving(replacement.items, true); } for (i = 0; i < len; ++i) { record = records[i]; if (!data.contains(record)) { if (removed && !isMove && !record.phantom && !record.erasing) { record.removedFrom = index + i; removed.push(record); me.needsSync = true; } else { record.unjoin(me); } } } if (!silent) { me.fireEvent('remove', me, records, index, isMove); if (lastChunk) { me.fireEvent('datachanged', me); } } if (replacement) { me.setMoving(replacement.items, false); } }, onFilterEndUpdate: function() { this.callParent(arguments); this.callObservers('Filter'); }, removeAt: function(index, count) { var data = this.getData(); index = Math.max(index, 0); if (index < data.length) { if (arguments.length === 1) { count = 1; } else if (!count) { return; } data.removeAt(index, count); } }, removeAll: function(silent) { var me = this, data = me.getData(), hasClear = me.hasListeners.clear, records = data.getRange(); if (data.length) { me.removeIsSilent = true; me.callObservers('BeforeRemoveAll'); data.removeAll(); me.removeIsSilent = false; if (!silent) { me.fireEvent('clear', me, records); me.fireEvent('datachanged', me); } me.callObservers('AfterRemoveAll', [ !!silent ]); } return records; }, setRecords: function(records) { var count = this.getCount(); ++this.loadCount; if (count) { this.getData().splice(0, count, records); } else { this.add(records); } }, splice: function(index, toRemove, toAdd) { return this.getData().splice(index, toRemove, toAdd); }, load: function(options) { var me = this, pageSize = me.getPageSize(), session; if (typeof options === 'function') { options = { callback: options }; } else { options = Ext.apply({}, options); } if (me.getRemoteSort() && !options.grouper && me.getGrouper()) { options.grouper = me.getGrouper(); } if (pageSize || 'start' in options || 'limit' in options || 'page' in options) { options.page = options.page != null ? options.page : me.currentPage; options.start = (options.start !== undefined) ? options.start : (options.page - 1) * pageSize; options.limit = options.limit != null ? options.limit : pageSize; me.currentPage = options.page; } options.addRecords = options.addRecords || false; if (!options.recordCreator) { session = me.getSession(); if (session) { options.recordCreator = session.recordCreator; } } return me.callParent([ options ]); }, onProxyLoad: function(operation) { var me = this, resultSet = operation.getResultSet(), records = operation.getRecords(), successful = operation.wasSuccessful(); if (me.isDestroyed) { return; } if (resultSet) { me.totalCount = resultSet.getTotal(); } if (successful) { records = me.processAssociation(records); me.loadRecords(records, operation.getAddRecords() ? { addRecords: true } : undefined); } else { me.loading = false; } if (me.hasListeners.load) { me.fireEvent('load', me, records, successful, operation); } me.callObservers('AfterLoad', [ records, successful, operation ]); }, getUnfiltered: function() { var data = this.getData(); return data.getSource() || data; }, getNewRecords: function() { return this.getUnfiltered().createFiltered(this.filterNew).getRange(); }, getUpdatedRecords: function() { return this.getUnfiltered().createFiltered(this.filterUpdated).getRange(); }, loadData: function(data, append) { var me = this, length = data.length, newData = [], i; for (i = 0; i < length; i++) { newData.push(me.createModel(data[i])); } newData = me.processAssociation(newData); me.loadRecords(newData, append ? me.addRecordsOptions : undefined); }, loadRawData: function(data, append) { var me = this, session = me.getSession(), result = me.getProxy().getReader().read(data, session ? { recordCreator: session.recordCreator } : undefined), records = result.getRecords(), success = result.getSuccess(); if (success) { me.totalCount = result.getTotal(); me.loadRecords(records, append ? me.addRecordsOptions : undefined); } return success; }, loadRecords: function(records, options) { var me = this, length = records.length, data = me.getData(), addRecords, i, skipSort; if (options) { addRecords = options.addRecords; } if (!me.getRemoteSort() && !me.getSortOnLoad()) { skipSort = true; data.setAutoSort(false); } if (!addRecords) { me.clearData(true); } me.loading = false; me.ignoreCollectionAdd = true; me.callObservers('BeforePopulate'); data.add(records); me.ignoreCollectionAdd = false; if (skipSort) { data.setAutoSort(true); } for (i = 0; i < length; i++) { records[i].join(me); } ++me.loadCount; me.complete = true; me.fireEvent('datachanged', me); me.fireEvent('refresh', me); me.callObservers('AfterPopulate'); }, loadPage: function(page, options) { var me = this, size = me.getPageSize(); me.currentPage = page; options = Ext.apply({ page: page, start: (page - 1) * size, limit: size, addRecords: !me.getClearOnPageLoad() }, options); me.read(options); }, nextPage: function(options) { this.loadPage(this.currentPage + 1, options); }, previousPage: function(options) { this.loadPage(this.currentPage - 1, options); }, clearData: function(isLoad) { var me = this, removed = me.removed, data = me.getData(), clearRemovedOnLoad = me.getClearRemovedOnLoad(), needsUnjoinCheck = removed && isLoad && !clearRemovedOnLoad, records, record, i, len, unjoin; data = data.getSource() || data; if (data) { records = data.items; for (i = 0 , len = records.length; i < len; ++i) { record = records[i]; if (needsUnjoinCheck && Ext.Array.contains(removed, record)) { continue; } record.unjoin(me); } me.ignoreCollectionRemove = true; me.callObservers('BeforeClear'); data.removeAll(); me.ignoreCollectionRemove = false; me.callObservers('AfterClear'); } if (removed && (!isLoad || clearRemovedOnLoad)) { removed.length = 0; } }, onIdChanged: function(rec, oldId, newId) { this.getData().updateKey(rec, oldId); this.fireEvent('idchanged', this, rec, oldId, newId); }, commitChanges: function() { var me = this, recs = me.getModifiedRecords(), len = recs.length, i = 0; Ext.suspendLayouts(); me.beginUpdate(); for (; i < len; i++) { recs[i].commit(); } me.cleanRemoved(); me.endUpdate(); Ext.resumeLayouts(true); }, filterNewOnly: function(item) { return item.phantom === true; }, filterRejects: function(item) { return item.phantom || item.dirty; }, getRejectRecords: function() { return this.getData().createFiltered(this.filterRejects).getRange(); }, rejectChanges: function() { var me = this, recs = me.getRejectRecords(), len = recs.length, i, rec, toRemove, sorted, data, currentAutoSort; Ext.suspendLayouts(); me.beginUpdate(); for (i = 0; i < len; i++) { rec = recs[i]; if (rec.phantom) { toRemove = toRemove || []; toRemove.push(rec); } else { rec.reject(); } } if (toRemove) { me.remove(toRemove); for (i = 0 , len = toRemove.length; i < len; ++i) { toRemove[i].reject(); } } recs = me.removed; if (recs) { len = recs.length; sorted = !me.getRemoteSort() && me.isSorted(); if (sorted) { data = me.getData(); currentAutoSort = data.getAutoSort(); data.setAutoSort(false); } for (i = len - 1; i >= 0; i--) { rec = recs[i]; rec.reject(); if (!sorted) { me.insert(rec.removedFrom || 0, rec); } } if (sorted) { data.setAutoSort(currentAutoSort); me.add(recs); } recs.length = 0; } me.endUpdate(); Ext.resumeLayouts(true); }, onDestroy: function() { var me = this, task = me.loadTask, data = me.getData(), source = data.getSource(); me.callParent(); me.setSession(null); me.observers = null; if (task) { task.cancel(); me.loadTask = null; } me.clearData(); data.destroy(); if (source) { source.destroy(); } me.setData(null); }, privates: { onBeforeLoad: function(operation) { this.callObservers('BeforeLoad', [ operation ]); }, onRemoteFilterSet: function(filters, remoteFilter) { if (filters) { this.getData().setFilters(remoteFilter ? null : filters); } this.callParent([ filters, remoteFilter ]); }, onRemoteSortSet: function(sorters, remoteSort) { var data = this.getData(); if (sorters) { data.setSorters(remoteSort ? null : sorters); } data.setAutoGroup(!remoteSort); this.callParent([ sorters, remoteSort ]); }, isMoving: function(records, getMap) { var map = this.moveMap, moving = 0, len, i; if (map) { if (records) { if (Ext.isArray(records)) { for (i = 0 , len = records.length; i < len; ++i) { moving += map[records[i].id] ? 1 : 0; } } else if (map[records.id]) { ++moving; } } else { moving = getMap ? map : this.moveMapCount; } } return moving; }, setMoving: function(records, isMoving) { var me = this, map = me.moveMap || (me.moveMap = {}), len = records.length, i, id; for (i = 0; i < len; ++i) { id = records[i].id; if (isMoving) { if (map[id]) { ++map[id]; } else { map[id] = 1; ++me.moveMapCount; } } else { if (--map[id] === 0) { delete map[id]; --me.moveMapCount; } } } if (me.moveMapCount === 0) { me.moveMap = null; } }, processAssociation: function(records) { var me = this, associatedEntity = me.getAssociatedEntity(); if (associatedEntity) { records = me.getRole().processLoad(me, associatedEntity, records, me.getSession()); } return records; } } }); Ext.define('Ext.data.reader.Array', { extend: 'Ext.data.reader.Json', alternateClassName: 'Ext.data.ArrayReader', alias: 'reader.array', config: { totalProperty: undefined, successProperty: undefined }, createFieldAccessor: function(field) { var oldMap = field.mapping, index = field.hasMapping() ? oldMap : field.ordinal, result; field.mapping = index; result = this.callParent(arguments); field.mapping = oldMap; return result; }, getModelData: function(raw) { return {}; } }); Ext.define('Ext.data.ArrayStore', { extend: 'Ext.data.Store', alias: 'store.array', alternateClassName: [ 'Ext.data.SimpleStore' ], requires: [ 'Ext.data.proxy.Memory', 'Ext.data.reader.Array' ], config: { proxy: { type: 'memory', reader: 'array' } }, loadData: function(data, append) { if (this.expandData) { var r = [], i = 0, ln = data.length; for (; i < ln; i++) { r[r.length] = [ data[i] ]; } data = r; } this.callParent([ data, append ]); } }); Ext.define('Ext.data.StoreManager', { extend: 'Ext.util.MixedCollection', alternateClassName: [ 'Ext.StoreMgr', 'Ext.data.StoreMgr', 'Ext.StoreManager' ], singleton: true, requires: [ '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 new Ext.data.ArrayStore({ data: data, fields: fields, autoDestroy: true, autoCreated: true, expanded: expand }); } if (Ext.isString(store)) { return this.get(store); } else { return Ext.Factory.store(store); } }, getKey: function(o) { return o.storeId; } }, function() { Ext.regStore = function(name, config) { var store; if (Ext.isObject(name)) { config = name; } else { if (Ext.data.StoreManager.containsKey(name)) { return Ext.data.StoreManager.lookup(name); } config.storeId = name; } if (config instanceof Ext.data.Store) { store = config; } else { store = new Ext.data.Store(config); } Ext.data.StoreManager.register(store); return store; }; Ext.getStore = function(name) { return Ext.data.StoreManager.lookup(name); }; var emptyStore = Ext.regStore('ext-empty-store', { proxy: 'memory', useModelWarning: false }); emptyStore.isEmptyStore = true; emptyStore.add = emptyStore.remove = emptyStore.insert = emptyStore.load = emptyStore.loadData = function() { Ext.Error.raise('Cannot modify ext-empty-store'); }; }); Ext.define('Ext.app.domain.Store', { extend: 'Ext.app.EventDomain', singleton: true, requires: [ 'Ext.data.AbstractStore' ], type: 'store', prefix: 'store.', idMatchRe: /^\#/, constructor: function() { var me = this; me.callParent(); me.monitor(Ext.data.AbstractStore); }, match: function(target, selector) { var result = false, alias = target.alias; if (selector === '*') { result = true; } else if (this.idMatchRe.test(selector)) { result = target.getStoreId() === selector.substring(1); } else if (alias) { result = Ext.Array.indexOf(alias, this.prefix + selector) > -1; } return result; } }); Ext.define('Ext.app.route.Queue', { queue: null, token: null, constructor: function(config) { Ext.apply(this, config); this.queue = new Ext.util.MixedCollection(); }, queueAction: function(route, args) { this.queue.add({ route: route, args: args }); }, clearQueue: function() { this.queue.removeAll(); }, runQueue: function() { var queue = this.queue, action = queue.removeAt(0), route; if (action) { route = action && action.route; route.execute(this.token, action.args, this.onActionExecute, this); } }, onActionExecute: function(clearQueue) { if (clearQueue) { this.clearQueue(); } else { this.runQueue(); } } }); Ext.define('Ext.app.route.Route', { action: null, conditions: null, controller: null, allowInactive: false, url: null, before: null, caseInsensitive: false, matcherRegex: null, paramMatchingRegex: null, paramsInMatchString: null, constructor: function(config) { var me = this, url; Ext.apply(me, config, { conditions: {} }); url = me.url; me.paramMatchingRegex = new RegExp(/:([0-9A-Za-z\_]*)/g); me.paramsInMatchString = url.match(me.paramMatchingRegex) || []; me.matcherRegex = me.createMatcherRegex(url); }, recognize: function(url) { var me = this, controller = me.controller, matches, args; if ((me.allowInactive || controller.isActive()) && me.recognizes(url)) { matches = me.matchesFor(url); args = url.match(me.matcherRegex); args.shift(); return Ext.applyIf(matches, { controller: controller, action: me.action, historyUrl: url, args: args }); } return false; }, recognizes: function(url) { return this.matcherRegex.test(url); }, execute: function(token, argConfig, callback, scope) { var args = argConfig.args || [], before = this.before, controller = this.controller, beforeCallback = this.createCallback(argConfig, callback, scope); if (before) { args.push(beforeCallback); if (Ext.isString(before)) { before = this.before = controller[before]; } if (before) { before.apply(controller, args); } else { Ext.log.warn('The before action: ' + this.before + ' was not found on the controller. The action method will not be executed.'); } } else { beforeCallback.resume(); } }, matchesFor: function(url) { var params = {}, keys = this.paramsInMatchString, values = url.match(this.matcherRegex), i = 0, len = keys.length; values.shift(); for (; i < len; i++) { params[keys[i].replace(':', '')] = values[i]; } return params; }, createMatcherRegex: function(url) { var paramsInMatchString = this.paramsInMatchString, conditions = this.conditions, i = 0, len = paramsInMatchString.length, format = Ext.util.Format.format, modifiers = this.caseInsensitive ? 'i' : '', params, cond, matcher; for (; i < len; i++) { params = paramsInMatchString[i]; cond = conditions[params]; matcher = format('{0}', cond || '([%a-zA-Z0-9\\-\\_\\s,]+)'); url = url.replace(new RegExp(params), matcher); } return new RegExp('^' + url + '$', modifiers); }, createCallback: function(args, callback, scope) { var me = this; scope = scope || me; return { resume: function() { var controller = me.controller, action = me.action, resume; if (Ext.isString(action)) { action = controller[action]; } args = args && args.args ? args.args : []; resume = args.pop(); if (resume && !Ext.isObject(resume)) { args.push(resume); } if (action) { me.action = action; action.apply(controller, args); } else { Ext.log.warn('The action: ' + me.action + ' was not found on the controller.'); } if (callback) { callback.call(scope); } }, stop: function(all) { if (callback) { callback.call(scope, all); } } }; } }); Ext.define('Ext.util.History', { singleton: true, alternateClassName: 'Ext.History', mixins: { observable: 'Ext.util.Observable' }, useTopWindow: false, constructor: function() { var me = this; me.hiddenField = null; me.ready = false; me.currentToken = null; me.mixins.observable.constructor.call(me); }, getHash: function() { return this.win.location.hash.substr(1); }, setHash: function(hash) { try { this.win.location.hash = hash; this.currentToken = hash; } catch (e) {} }, handleStateChange: function(token) { this.currentToken = token; this.fireEvent('change', token); }, startUp: function() { var me = this; me.currentToken = me.getHash(); if (Ext.supports.Hashchange) { Ext.get(me.win).on('hashchange', me.onHashChange, me); } else { Ext.TaskManager.start({ fireIdleEvent: false, run: me.onHashChange, interval: 50, scope: me }); } me.ready = true; me.fireEvent('ready', me); }, onHashChange: function() { var me = this, newHash = me.getHash(); if (newHash !== me.hash) { me.hash = newHash; me.handleStateChange(newHash); } }, init: function(onReady, scope) { var me = this; if (me.ready) { Ext.callback(onReady, scope, [ me ]); return; } if (!Ext.isReady) { Ext.onInternalReady(function() { me.init(onReady, scope); }); return; } me.win = me.useTopWindow ? window.top : window; me.hash = me.getHash(); if (onReady) { me.on('ready', onReady, scope, { single: true }); } me.startUp(); }, add: function(token, preventDuplicates) { var me = this, set = false; if (preventDuplicates === false || me.getToken() !== token) { me.setHash(token); set = true; } return set; }, back: function() { var win = this.useTopWindow ? window.top : window; win.history.go(-1); }, forward: function() { var win = this.useTopWindow ? window.top : window; win.history.go(1); }, getToken: function() { return this.ready ? this.currentToken : this.getHash(); } }); Ext.define('Ext.app.route.Router', { singleton: true, requires: [ 'Ext.app.route.Queue', 'Ext.app.route.Route', 'Ext.util.History' ], multipleToken: '|', queueRoutes: true, constructor: function() { var History = Ext.util.History; if (!History.ready) { History.init(); } History.on('change', this.onStateChange, this); this.clear(); }, onStateChange: function(token) { var me = this, app = me.application, routes = me.routes, len = routes.length, queueRoutes = me.queueRoutes, tokens = token.split(me.multipleToken), t = 0, length = tokens.length, i, queue, route, args, matched; for (; t < length; t++) { token = tokens[t]; matched = false; if (queueRoutes) { queue = new Ext.app.route.Queue({ token: token }); } for (i = 0; i < len; i++) { route = routes[i]; args = route.recognize(token); if (args) { matched = true; if (queueRoutes) { queue.queueAction(route, args); } else { route.execute(token, args); } } } if (queueRoutes) { queue.runQueue(); } if (!matched && app) { app.fireEvent('unmatchedroute', token); } } }, connect: function(url, action, controller) { var config = { url: url, action: action, controller: controller }; if (Ext.isObject(action)) { Ext.merge(config, action); } this.routes.push(new Ext.app.route.Route(config)); }, disconnectAll: function(controller) { var routes = this.routes, len = routes.length, newRoutes = [], i, route; for (i = 0; i < len; ++i) { route = routes[i]; if (route.controller !== controller) { newRoutes.push(route); } } this.routes = newRoutes; }, recognize: function(url) { var routes = this.routes || [], i = 0, len = routes.length, route, args; for (; i < len; i++) { route = routes[i]; args = route.recognize(url); if (args) { return { route: route, args: args }; } } return false; }, draw: function(fn) { fn.call(this, this); }, clear: function() { this.routes = []; } }); Ext.define('Ext.app.Controller', { extend: 'Ext.app.BaseController', requires: [ 'Ext.app.Util', 'Ext.data.StoreManager', 'Ext.ComponentManager', 'Ext.app.domain.Component', 'Ext.app.domain.Store', 'Ext.app.route.Router' ], statics: { strings: { model: { getter: 'getModel', upper: 'Model' }, view: { getter: 'getView', upper: 'View' }, controller: { getter: 'getController', upper: 'Controller' }, store: { getter: 'getStore', upper: 'Store' }, profile: { getter: 'getProfile', upper: 'Profiles' } }, controllerRegex: /^(.*)\.controller\./, createGetter: function(baseGetter, name) { return function() { return this[baseGetter](name); }; }, getGetterName: function(name, kindUpper) { var fn = 'get', parts = name.split('.'), numParts = parts.length, index; for (index = 0; index < numParts; index++) { fn += Ext.String.capitalize(parts[index]); } fn += kindUpper; return fn; }, resolveNamespace: function(cls, data) { var Controller = Ext.app.Controller, ctrlRegex = Controller.controllerRegex, className, namespace, match; className = Ext.getClassName(cls); namespace = data.$namespace || data.namespace || Ext.app.getNamespace(className) || ((match = ctrlRegex.exec(className)) && match[1]); if (!namespace) { Ext.log.warn("Missing namespace for " + className + ", please define it " + "in namespaces property of your Application class."); } return namespace; }, processDependencies: function(cls, requires, namespace, kind, names) { if (!names || !names.length) { return; } var me = this, strings = me.strings[kind], o, absoluteName, shortName, name, j, subLn, getterName, getter; if (!Ext.isArray(names)) { names = [ names ]; } for (j = 0 , subLn = names.length; j < subLn; j++) { name = names[j]; o = me.getFullName(name, kind, namespace); absoluteName = o.absoluteName; shortName = o.shortName; requires.push(absoluteName); getterName = me.getGetterName(shortName, strings.upper); cls[getterName] = getter = me.createGetter(strings.getter, name); if (kind !== 'controller') { getter['Ext.app.getter'] = true; } } }, getFullName: function(name, kind, namespace) { var shortName = name, sep, absoluteName; if ((sep = name.indexOf('@')) > 0) { shortName = name.substring(0, sep); absoluteName = name.substring(sep + 1) + '.' + shortName; } else if (name.indexOf('.') > 0 && (Ext.ClassManager.isCreated(name) || this.hasRegisteredPrefix(name))) { absoluteName = name; } else { if (!namespace) { Ext.log.warn("Cannot find namespace for " + kind + " " + name + ", " + "assuming it is fully qualified class name"); } if (namespace) { absoluteName = namespace + '.' + kind + '.' + name; shortName = name; } else { absoluteName = name; } } return { absoluteName: absoluteName, shortName: shortName }; }, hasRegisteredPrefix: function(className) { var inventory = Ext.ClassManager, prefix = inventory.getPrefix(className); return prefix && prefix !== className; } }, models: null, views: null, stores: null, controllers: null, config: { application: null, refs: null, active: true, moduleClassName: null }, onClassExtended: function(cls, data, hooks) { var onBeforeClassCreated = hooks.onBeforeCreated; hooks.onBeforeCreated = function(cls, data) { var Controller = Ext.app.Controller, requires = [], namespace, proto; proto = cls.prototype; namespace = Controller.resolveNamespace(cls, data); if (namespace) { proto.$namespace = namespace; } Controller.processDependencies(proto, requires, namespace, 'model', data.models); Controller.processDependencies(proto, requires, namespace, 'view', data.views); Controller.processDependencies(proto, requires, namespace, 'store', data.stores); Controller.processDependencies(proto, requires, namespace, 'controller', data.controllers); Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this)); }; }, constructor: function(config) { this.initAutoGetters(); this.callParent(arguments); }, normalizeRefs: function(refs) { var me = this, newRefs = []; if (refs) { if (Ext.isObject(refs)) { Ext.Object.each(refs, function(key, value) { if (Ext.isString(value)) { value = { selector: value }; } value.ref = key; newRefs.push(value); }); } else if (Ext.isArray(refs)) { newRefs = Ext.Array.merge(newRefs, refs); } } refs = me.refs; if (refs) { me.refs = null; refs = me.normalizeRefs(refs); if (refs) { newRefs = Ext.Array.merge(newRefs, refs); } } return newRefs; }, getRefMap: function() { var me = this, refMap = me._refMap, refs, ref, ln, i; if (!refMap) { refs = me.getRefs(); refMap = me._refMap = {}; if (refs) { for (i = 0 , ln = refs.length; i < ln; i++) { ref = refs[i]; refMap[ref.ref] = ref.selector; } } } return refMap; }, applyRefs: function(refs) { return this.normalizeRefs(Ext.clone(refs)); }, updateRefs: function(refs) { if (refs) { this.ref(refs); } }, initAutoGetters: function() { var proto = this.self.prototype, prop, fn; for (prop in proto) { fn = proto[prop]; if (fn && fn['Ext.app.getter']) { fn.call(this); } } }, doInit: function(app) { var me = this; if (!me._initialized) { me.init(app); me._initialized = true; } }, finishInit: function(app) { var me = this, controllers = me.controllers, controller, i, l; if (me._initialized && controllers && controllers.length) { for (i = 0 , l = controllers.length; i < l; i++) { controller = me.getController(controllers[i]); controller.finishInit(app); } } }, init: Ext.emptyFn, onLaunch: Ext.emptyFn, activate: function() { this.setActive(true); }, deactivate: function() { this.setActive(false); }, isActive: function() { return this.getActive(); }, ref: function(refs) { var me = this, i = 0, length = refs.length, info, ref, fn; refs = Ext.Array.from(refs); me.references = me.references || []; for (; i < length; i++) { info = refs[i]; ref = info.ref; fn = 'get' + Ext.String.capitalize(ref); if (!me[fn]) { me[fn] = Ext.Function.pass(me.getRef, [ ref, info ], me); } me.references.push(ref.toLowerCase()); } }, addRef: function(refs) { this.ref(refs); }, getRef: function(ref, info, config) { var me = this, refCache = me.refCache || (me.refCache = {}), cached = refCache[ref]; info = info || {}; config = config || {}; Ext.apply(info, config); if (info.forceCreate) { return Ext.ComponentManager.create(info, 'component'); } if (!cached) { if (info.selector) { refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0]; } if (!cached && info.autoCreate) { refCache[ref] = cached = Ext.ComponentManager.create(info, 'component'); } if (cached) { cached.on('beforedestroy', function() { refCache[ref] = null; }); } } return cached; }, hasRef: function(ref) { var references = this.references; return references && Ext.Array.indexOf(references, ref.toLowerCase()) !== -1; }, getController: function(id) { var app = this.getApplication(); if (id === this.getId()) { return this; } return app && app.getController(id); }, getStore: function(name) { var storeId, store; storeId = (name.indexOf('@') === -1) ? name : name.split('@')[0]; store = Ext.StoreManager.get(storeId); if (!store) { name = Ext.app.Controller.getFullName(name, 'store', this.$namespace); if (name) { store = Ext.create(name.absoluteName, { storeId: storeId }); } } return store; }, getModel: function(model) { var name = Ext.app.Controller.getFullName(model, 'model', this.$namespace), ret = Ext.ClassManager.get(name.absoluteName); if (!ret) { ret = Ext.data.schema.Schema.lookupEntity(model); } return ret; }, getProfile: function(name) { name = Ext.app.Controller.getFullName(name, 'profile', this.$namespace); return name; }, getView: function(view) { var name = Ext.app.Controller.getFullName(view, 'view', this.$namespace); return name && Ext.ClassManager.get(name.absoluteName); }, ensureId: function() { var id = this.getId(); if (!id) { this.setId(this.getModuleClassName(this.$className, 'controller')); } }, destroy: function(destroyRefs, fromApp) { var me = this, app = me.application, refCache, ref; if (!fromApp && app) { app.unregister(me); } me.application = null; if (destroyRefs) { refCache = me.refCache; for (ref in refCache) { if (refCache.hasOwnProperty(ref)) { Ext.destroy(refCache[ref]); } } } me.callParent(); } }); Ext.define('Ext.app.Application', { extend: 'Ext.app.Controller', requires: [ 'Ext.util.History', 'Ext.util.MixedCollection' ], isApplication: true, scope: undefined, namespaces: [], paths: null, appFolder: 'app', config: { name: '', appProperty: 'app', profiles: [], currentProfile: null, mainView: { $value: null, lazy: true }, defaultToken: null, glyphFontFamily: null }, onClassExtended: function(cls, data, hooks) { var Controller = Ext.app.Controller, proto = cls.prototype, requires = [], onBeforeClassCreated, paths, namespace, ns, appFolder; namespace = data.name || cls.superclass.name; appFolder = data.appFolder || cls.superclass.appFolder; if (namespace) { data.$namespace = namespace; Ext.app.addNamespaces(namespace); } if (data.namespaces) { Ext.app.addNamespaces(data.namespaces); } if (!data['paths processed']) { if (namespace && appFolder) { Ext.Loader.setPath(namespace, appFolder); } paths = data.paths; if (paths) { for (ns in paths) { if (paths.hasOwnProperty(ns)) { Ext.Loader.setPath(ns, paths[ns]); } } } } else { delete data['paths processed']; } Controller.processDependencies(proto, requires, namespace, 'profile', data.profiles); proto.getDependencies(cls, data, requires); if (requires.length) { onBeforeClassCreated = hooks.onBeforeCreated; hooks.onBeforeCreated = function(cls, data) { var args = Ext.Array.clone(arguments); Ext.require(requires, function() { return onBeforeClassCreated.apply(this, args); }); }; } }, getDependencies: Ext.emptyFn, constructor: function(config) { var me = this; Ext.app.route.Router.application = me; me.callParent(arguments); if (Ext.isEmpty(me.getName())) { Ext.Error.raise("[Ext.app.Application] Name property is required"); } me.doInit(me); me.initNamespace(); Ext.Loader.setConfig({ enabled: true }); var profiles = this.getProfiles(); if (profiles && profiles.length) { Ext.require(profiles, this.onProfilesLoaded, this); } else { this.onProfilesReady(); } }, onProfilesReady: function() { var me = this; me.initControllers(); me.onBeforeLaunch(); me.finishInitControllers(); }, initNamespace: function() { var me = this, appProperty = me.getAppProperty(), ns; ns = Ext.namespace(me.getName()); if (ns) { ns.getApplication = function() { return me; }; if (appProperty) { if (!ns[appProperty]) { ns[appProperty] = me; } else if (ns[appProperty] !== me) { Ext.log.warn('An existing reference is being overwritten for ' + name + '.' + appProperty + '. See the appProperty config.'); } } } }, initControllers: function() { var me = this, controllers = Ext.Array.from(me.controllers); me.controllers = new Ext.util.MixedCollection(); for (var i = 0, ln = controllers.length; i < ln; i++) { me.getController(controllers[i]); } }, finishInitControllers: function() { var me = this, controllers, i, l; controllers = me.controllers.getRange(); for (i = 0 , l = controllers.length; i < l; i++) { controllers[i].finishInit(me); } }, launch: Ext.emptyFn, onBeforeLaunch: function() { var me = this, History = Ext.util.History, defaultToken = me.getDefaultToken(), currentProfile = me.getCurrentProfile(), controllers, c, cLen, controller, token; me.initMainView(); if (currentProfile) { currentProfile.launch(); } me.launch.call(me.scope || me); me.launched = true; me.fireEvent('launch', me); controllers = me.controllers.items; cLen = controllers.length; for (c = 0; c < cLen; c++) { controller = controllers[c]; controller.onLaunch(me); } if (!History.ready) { History.init(); } token = History.getToken(); if (token) { Ext.app.route.Router.onStateChange(token); } else if (defaultToken) { History.add(defaultToken); } }, getModuleClassName: function(name, kind) { return Ext.app.Controller.getFullName(name, kind, this.getName()).absoluteName; }, initMainView: function() { var me = this, currentProfile = me.getCurrentProfile(), mainView; if (currentProfile) { mainView = currentProfile.getMainView(); } if (mainView) { me.setMainView(mainView); } else { me.getMainView(); } }, applyMainView: function(value) { var view; view = this.getView(value); return view.create(); }, createController: function(name) { return this.getController(name); }, destroyController: function(controller) { if (typeof controller === 'string') { controller = this.getController(controller, true); } Ext.destroy(controller); }, getController: function(name, preventCreate) { var me = this, controllers = me.controllers, className, controller, len, i, c, all; controller = controllers.get(name); if (!controller) { all = controllers.items; for (i = 0 , len = all.length; i < len; ++i) { c = all[i]; className = c.getModuleClassName(); if (className && className === name) { controller = c; break; } } } if (!controller && !preventCreate) { className = me.getModuleClassName(name, 'controller'); controller = Ext.create(className, { application: me, moduleClassName: name }); controllers.add(controller); if (me._initialized) { controller.doInit(me); } } return controller; }, unregister: function(controller) { this.controllers.remove(controller); }, getApplication: function() { return this; }, destroy: function(destroyRefs) { var me = this, controllers = me.controllers, ns = Ext.namespace(me.getName()), appProp = me.getAppProperty(); Ext.destroy(me.viewport); if (controllers) { controllers.each(function(controller) { controller.destroy(destroyRefs, true); }); } me.controllers = null; me.callParent([ destroyRefs, true ]); if (ns && ns[appProp] === me) { delete ns[appProp]; } }, updateGlyphFontFamily: function(fontFamily) { Ext.setGlyphFontFamily(fontFamily); }, applyProfiles: function(profiles) { var me = this; return Ext.Array.map(profiles, function(profile) { return me.getModuleClassName(profile, "profile"); }); }, onProfilesLoaded: function() { var me = this, profiles = me.getProfiles(), length = profiles.length, instances = [], current, i, profileDeps, requires, controllers, profileControllers, views, profileViews, stores, profileStores, models, profileModels; for (i = 0; i < length; i++) { instances[i] = Ext.create(profiles[i], { application: me }); if (instances[i].isActive() && !current) { current = instances[i]; profileDeps = current.getDependencies(); requires = profileDeps.all; me.setCurrentProfile(current); profileControllers = profileDeps.controller; if (profileControllers.length) { controllers = me.controllers = (me.controllers || []); controllers.push.apply(controllers, profileControllers); } profileViews = profileDeps.view; if (profileViews.length) { views = me.views = (me.views || []); views.push.apply(views, profileViews); } profileStores = profileDeps.store; if (profileStores.length) { stores = me.stores = (me.stores || []); stores.push.apply(stores, profileStores); } profileModels = profileDeps.model; if (profileModels.length) { models = me.models = (me.models || []); models.push.apply(models, profileModels); } } } if (requires) { Ext.require(requires, me.onProfilesReady, me); } else { me.onProfilesReady(); } } }); Ext.application = function(config) { var createApp = function(App) { Ext.onReady(function() { Ext.app.Application.instance = new App(); }); }, paths = config.paths, ns; if (typeof config === "string") { Ext.require(config, function() { createApp(Ext.ClassManager.get(config)); }); } else { config = Ext.apply({ extend: 'Ext.app.Application' }, config); Ext.Loader.setPath(config.name, config.appFolder || 'app'); if (paths) { for (ns in paths) { if (paths.hasOwnProperty(ns)) { Ext.Loader.setPath(ns, paths[ns]); } } } config['paths processed'] = true; Ext.define(config.name + ".$application", config, function() { createApp(this); }); } }; Ext.define('Ext.overrides.app.Application', { override: 'Ext.app.Application', uses: [ 'Ext.tip.QuickTipManager' ], autoCreateViewport: false, config: { enableQuickTips: true }, applyMainView: function(value) { var view = this.getView(value), proto = view.prototype, config, plugins; if (!proto.isViewport) { plugins = proto.plugins; plugins = [ 'viewport' ].concat(plugins ? Ext.Array.from(plugins, true) : []); config = { plugins: plugins }; } return view.create(config); }, getDependencies: function(cls, data, requires) { var Controller = Ext.app.Controller, proto = cls.prototype, namespace = data.$namespace, viewportClass = data.autoCreateViewport; if (viewportClass) { if (!namespace) { Ext.Error.raise("[Ext.app.Application] Can't resolve namespace for " + data.$className + ", did you forget to specify 'name' property?"); } if (viewportClass === true) { viewportClass = 'Viewport'; } else { requires.push('Ext.plugin.Viewport'); } Controller.processDependencies(proto, requires, namespace, 'view', viewportClass); } }, onBeforeLaunch: function() { var me = this, autoCreateViewport = me.autoCreateViewport; if (me.getEnableQuickTips()) { me.initQuickTips(); } if (autoCreateViewport) { me.initViewport(); } this.callParent(arguments); }, getViewportName: function() { var name = null, autoCreate = this.autoCreateViewport; if (autoCreate) { name = (autoCreate === true) ? 'Viewport' : autoCreate; } return name; }, initViewport: function() { this.setMainView(this.getViewportName()); }, initQuickTips: function() { Ext.tip.QuickTipManager.init(); } }); Ext.define('Ext.app.Profile', { mixins: { observable: "Ext.mixin.Observable" }, config: { namespace: 'auto', name: 'auto', mainView: { $value: null, lazy: true }, application: null, controllers: [], models: [], views: [], stores: [] }, constructor: function(config) { this.initConfig(config); this.mixins.observable.constructor.apply(this, arguments); }, isActive: function() { return false; }, launch: Ext.emptyFn, applyNamespace: function(name) { if (name == 'auto') { name = this.getName(); } return name.toLowerCase(); }, applyName: function(name) { if (name == 'auto') { var pieces = this.$className.split('.'); name = pieces[pieces.length - 1]; } return name; }, onClassExtended: function(cls, data, hooks) { var onBeforeClassCreated = hooks.onBeforeCreated; hooks.onBeforeCreated = function(cls, data) { var Controller = Ext.app.Controller, requires = [], proto = cls.prototype, namespace; namespace = Controller.resolveNamespace(cls, data); Controller.processDependencies(proto, requires, namespace, 'model', data.models); Controller.processDependencies(proto, requires, namespace, 'view', data.views); Controller.processDependencies(proto, requires, namespace, 'store', data.stores); Controller.processDependencies(proto, requires, namespace, 'controller', data.controllers); Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this)); }; }, getDependencies: function() { var allClasses = [], appName = this.getApplication().getName(), namespace = this.getNamespace(), map = { model: this.getModels(), view: this.getViews(), controller: this.getControllers(), store: this.getStores() }, classType, classNames; for (classType in map) { classNames = []; Ext.each(map[classType], function(className) { if (Ext.isString(className)) { if (Ext.isString(className) && (Ext.ClassManager.getPrefix(className) === "" || className === appName)) { className = appName + '.' + classType + '.' + namespace + '.' + className; } classNames.push(className); allClasses.push(className); } }, this); map[classType] = classNames; } map.all = allClasses; return map; } }); Ext.define('Ext.app.domain.View', { extend: 'Ext.app.EventDomain', isInstance: true, constructor: function(controller) { this.callParent(arguments); this.controller = controller; this.monitoredClasses = [ Ext.Component ]; }, match: function(target, selector, controller) { var out = false; if (selector === '#') { out = controller === target.getController(); } else { out = target.is(selector); } return out; }, destroy: function() { this.controller = null; this.callParent(); } }); Ext.define('Ext.app.ViewController', { extend: 'Ext.app.BaseController', requires: [ 'Ext.app.domain.View' ], mixins: [ 'Ext.mixin.Factoryable' ], isViewController: true, factoryConfig: { type: 'controller' }, config: { closeViewAction: 'destroy' }, constructor: function() { this.compDomain = new Ext.app.domain.View(this); this.callParent(arguments); }, beforeInit: Ext.emptyFn, init: Ext.emptyFn, initViewModel: Ext.emptyFn, destroy: function() { var me = this, domain = me.compDomain; if (domain) { domain.unlisten(me); domain.destroy(); } me.compDomain = me.view = null; me.callParent(); }, closeView: function() { var view = this.getView(), action; if (view) { action = this.getCloseViewAction(); view[action](); } }, control: function(selectors, listeners) { var obj = selectors; if (Ext.isString(selectors)) { obj = {}; obj[selectors] = listeners; } this.compDomain.listen(obj, this); }, listen: function(to, controller) { var component = to.component; if (component) { to = Ext.apply({}, to); delete to.component; this.control(component); } this.callParent([ to, controller ]); }, getReferences: function() { return this.view.getReferences(); }, getView: function() { return this.view; }, lookupReference: function(key) { var view = this.view; return view && view.lookupReference(key); }, getSession: function() { var view = this.view; return view && view.lookupSession(); }, getViewModel: function() { var view = this.view; return view && view.lookupViewModel(); }, getStore: function(name) { var viewModel = this.getViewModel(); return viewModel ? viewModel.getStore(name) : null; }, fireViewEvent: function(eventName) { var view = this.view, result = false; if (view) { result = view.fireEvent.apply(view, arguments); } return result; }, privates: { view: null, ensureId: function() { var id = this.getId(); if (!id) { this.setId(Ext.id(null, 'controller-')); } }, attachReference: function(component) { var view = this.view; if (view) { view.attachReference(component); } }, clearReference: function(ref) { var view = this.view; if (view) { view.clearReference(ref); } }, clearReferences: function() { var view = this.view; if (view) { view.clearReferences(); } }, setView: function(view) { this.view = view; if (!this.beforeInit.$nullFn) { this.beforeInit(view); } } } }); Ext.define('Ext.util.Bag', { isBag: true, constructor: function() { this.items = []; this.map = {}; }, generation: 0, length: 0, add: function(item) { var me = this, id = me.getKey(item), map = me.map, items = me.items, idx = map[id], old; if (idx === undefined) { items.push(item); map[id] = me.length++; old = item; } else { old = items[idx]; items[idx] = item; } ++me.generation; return old; }, clear: function() { var me = this, needsClear = me.generation || me.length, ret = needsClear ? me.items : []; if (needsClear) { me.items = []; me.length = 0; me.map = {}; ++me.generation; } return ret; }, clone: function() { var me = this, ret = new me.self(), len = me.length; if (len) { Ext.apply(ret.map, me.map); ret.items = me.items.slice(); ret.length = me.length; } return ret; }, contains: function(item) { var ret = false, map = this.map, key; if (item != null) { key = this.getKey(item); if (key in map) { ret = this.items[map[key]] === item; } } return ret; }, containsKey: function(key) { return key in this.map; }, destroy: function() { this.items = this.map = null; this.callParent(); }, getAt: function(index) { var out = null; if (index < this.length) { out = this.items[index]; } return out; }, getByKey: function(key) { var map = this.map, ret = null; if (key in map) { ret = this.items[map[key]]; } return ret; }, getCount: function() { return this.length; }, getKey: function(item) { return item.id || item.getId(); }, remove: function(item) { var me = this, map = me.map, items = me.items, old = null, idx, id, last; if (me.length) { idx = map[id = me.getKey(item)]; if (idx !== undefined) { delete map[id]; old = items[idx]; last = items.pop(); if (idx < --me.length) { items[idx] = last; map[me.getKey(last)] = idx; } ++me.generation; } } return old; }, removeByKey: function(key) { var item = this.getByKey(key); if (item) { this.remove(item); } return item || null; }, sort: function(fn) { var me = this, items = me.items, n = items.length, item; if (n) { Ext.Array.sort(items, fn); me.map = {}; while (n-- > 0) { item = items[n]; me.map[me.getKey(item)] = n; } ++me.generation; } } }); Ext.define('Ext.util.Scheduler', { mixins: [ 'Ext.mixin.Observable' ], requires: [ 'Ext.util.Bag' ], busyCounter: 0, lastBusyCounter: 0, destroyed: false, firing: null, notifyIndex: -1, nextId: 0, orderedItems: null, passes: 0, scheduledCount: 0, validIdRe: null, config: { cycleLimit: 5, preSort: null, tickDelay: 5 }, constructor: function(config) { if (Ext.util.Scheduler.instances) { Ext.util.Scheduler.instances.push(this); } else { Ext.util.Scheduler.instances = [ this ]; } this.id = Ext.util.Scheduler.count = (Ext.util.Scheduler.count || 0) + 1; this.mixins.observable.constructor.call(this, config); this.items = new Ext.util.Bag(); }, destroy: function() { var me = this, timer = me.timer; if (timer) { window.clearTimeout(timer); me.timer = null; } me.destroyed = true; me.items.destroy(); me.items = me.orderedItems = null; me.destroy = Ext.emptyFn; Ext.Array.remove(Ext.util.Scheduler.instances, this); }, add: function(item) { var me = this, items = me.items; if (items === me.firing) { me.items = items = items.clone(); } item.id = item.id || ++me.nextId; item.scheduler = me; items.add(item); if (!me.sortMap) { me.orderedItems = null; } }, remove: function(item) { var me = this, items = me.items; if (me.destroyed) { return; } if (me.sortMap) { Ext.Error.raise('Items cannot be removed during sort'); } if (items === me.firing) { me.items = items = items.clone(); } if (item.scheduled) { me.unscheduleItem(item); item.scheduled = false; } items.remove(item); me.orderedItems = null; }, sort: function() { var me = this, items = me.items, sortMap = {}, preSort = me.getPreSort(), i, item; me.orderedItems = []; me.sortMap = sortMap; me.sortStack = []; if (preSort) { items.sort(preSort); } items = items.items; for (i = 0; i < items.length; ++i) { item = items[i]; if (!sortMap[item.id]) { me.sortItem(item); } } me.sortMap = null; me.sortStack = null; }, sortItem: function(item) { var me = this, sortMap = me.sortMap, orderedItems = me.orderedItems, itemId; if (!item.scheduler) { me.add(item); } itemId = item.id; if (item.scheduler !== me) { Ext.Error.raise('Item ' + itemId + ' belongs to another Scheduler'); } me.sortStack.push(item); if (sortMap[itemId] === 0) { for (var cycle = [], i = 0; i < me.sortStack.length; ++i) { cycle[i] = me.sortStack[i].getFullName(); } Ext.Error.raise('Dependency cycle detected: ' + cycle.join('\n --> ')); } if (!(itemId in sortMap)) { sortMap[itemId] = 0; if (!item.sort.$nullFn) { item.sort(); } sortMap[itemId] = 1; item.order = me.orderedItems.length; orderedItems.push(item); } me.sortStack.pop(); return me; }, sortItems: function(items) { var me = this, sortItem = me.sortItem; if (items) { if (items instanceof Array) { Ext.each(items, sortItem, me); } else { Ext.Object.eachValue(items, sortItem, me); } } return me; }, applyPreSort: function(preSort) { if (typeof preSort === 'function') { return preSort; } var parts = preSort.split(','), direction = [], length = parts.length, c, i, s; for (i = 0; i < length; ++i) { direction[i] = 1; s = parts[i]; if ((c = s.charAt(0)) === '-') { direction[i] = -1; } else if (c !== '+') { c = 0; } if (c) { parts[i] = s.substring(1); } } return function(lhs, rhs) { var ret = 0, i, prop, v1, v2; for (i = 0; !ret && i < length; ++i) { prop = parts[i]; v1 = lhs[prop]; v2 = rhs[prop]; ret = direction[i] * ((v1 < v2) ? -1 : ((v2 < v1) ? 1 : 0)); } return ret; }; }, notify: function() { var me = this, timer = me.timer, cyclesLeft = me.getCycleLimit(), globalEvents = Ext.GlobalEvents, busyCounter, i, item, len, queue, firedEvent; if (timer) { window.clearTimeout(timer); me.timer = null; } if (me.firing) { Ext.Error.raise('Notify cannot be called recursively'); } while (me.scheduledCount) { if (cyclesLeft) { --cyclesLeft; } else { me.firing = null; if (me.onCycleLimitExceeded) { me.onCycleLimitExceeded(); } break; } if (!firedEvent) { firedEvent = true; if (globalEvents.hasListeners.beforebindnotify) { globalEvents.fireEvent('beforebindnotify', me); } } ++me.passes; if (!(queue = me.orderedItems)) { me.sort(); queue = me.orderedItems; } len = queue.length; if (len) { me.firing = me.items; for (i = 0; i < len; ++i) { item = queue[i]; if (item.scheduled) { item.scheduled = false; --me.scheduledCount; me.notifyIndex = i; item.react(); if (!me.scheduledCount) { break; } } } } } me.firing = null; me.notifyIndex = -1; if ((busyCounter = me.busyCounter) !== me.lastBusyCounter) { if (!(me.lastBusyCounter = busyCounter)) { me.fireEvent('idle', me); } } }, onTick: function() { this.timer = null; this.notify(); }, scheduleItem: function(item) { var me = this; ++me.scheduledCount; if (!me.timer && !me.firing) { me.scheduleTick(); } }, scheduleTick: function() { var me = this; if (!me.destroyed && !me.timer) { me.timer = Ext.Function.defer(me.onTick, me.getTickDelay(), me); } }, unscheduleItem: function(item) { if (this.scheduledCount) { --this.scheduledCount; } }, adjustBusy: function(adjustment) { var me = this, busyCounter = me.busyCounter + adjustment; me.busyCounter = busyCounter; if (busyCounter) { if (!me.lastBusyCounter) { me.lastBusyCounter = busyCounter; me.fireEvent('busy', me); } } else if (me.lastBusyCounter && !me.timer) { me.scheduleTick(); } }, isBusy: function() { return !this.isIdle(); }, isIdle: function() { return !(this.busyCounter + this.lastBusyCounter); }, debugHooks: { $enabled: false, onCycleLimitExceeded: function() { Ext.Error.raise('Exceeded cycleLimit ' + this.getCycleLimit()); }, scheduleItem: function(item) { if (!item) { Ext.Error.raise('scheduleItem: Invalid argument'); } Ext.log('Schedule item: ' + item.getFullName() + ' - ' + (this.scheduledCount + 1)); if (item.order <= this.notifyIndex) { Ext.log.warn('Suboptimal order: ' + item.order + ' < ' + this.notifyIndex); } this.callParent([ item ]); }, unscheduleItem: function(item) { if (!this.scheduledCount) { Ext.Error.raise('Invalid scheduleCount'); } this.callParent([ item ]); Ext.log('Unschedule item: ' + item.getFullName() + ' - ' + this.scheduledCount); } } }); Ext.define('Ext.data.Batch', { mixins: { observable: 'Ext.mixin.Observable' }, config: { pauseOnException: false }, current: -1, total: 0, running: false, complete: false, exception: false, constructor: function(config) { var me = this; me.mixins.observable.constructor.call(me, config); me.operations = []; me.exceptions = []; }, add: function(operation) { var me = this, i, len; if (Ext.isArray(operation)) { for (i = 0 , len = operation.length; i < len; ++i) { me.add(operation[i]); } } else { me.total++; operation.setBatch(me); me.operations.push(operation); } return me; }, sort: function() { this.operations.sort(this.sortFn); }, sortFn: function(operation1, operation2) { var ret = operation1.order - operation2.order; if (ret) { return ret; } var entityType1 = operation1.entityType, entityType2 = operation2.entityType, rank; if (!entityType1 || !entityType2) { return 0; } if (!(rank = entityType1.rank)) { entityType1.schema.rankEntities(); rank = entityType1.rank; } return (rank - entityType2.rank) * operation1.foreignKeyDirection; }, start: function( index) { var me = this; if (!me.operations.length || me.running) { return me; } me.exceptions.length = 0; me.exception = false; me.running = true; return me.runOperation(Ext.isDefined(index) ? index : me.current + 1); }, retry: function() { return this.start(this.current); }, runNextOperation: function() { var me = this; if (me.running) { me.runOperation(me.current + 1); } return me; }, pause: function() { this.running = false; return this; }, getOperations: function() { return this.operations; }, getExceptions: function() { return this.exceptions; }, getCurrent: function() { var out = null, current = this.current; if (!(current === -1 || this.complete)) { out = this.operations[current]; } return out; }, getTotal: function() { return this.total; }, isRunning: function() { return this.running; }, isComplete: function() { return this.complete; }, hasException: function() { return this.exception; }, runOperation: function(index) { var me = this, operations = me.operations, operation = operations[index]; if (operation === undefined) { me.running = false; me.complete = true; me.fireEvent('complete', me, operations[operations.length - 1]); } else { me.current = index; operation.setInternalCallback(me.onOperationComplete); operation.setInternalScope(me); operation.execute(); } return me; }, onOperationComplete: function(operation) { var me = this, exception = operation.hasException(); if (exception) { me.exception = true; me.exceptions.push(operation); me.fireEvent('exception', me, operation); } if (exception && me.getPauseOnException()) { me.pause(); } else { me.fireEvent('operationcomplete', me, operation); me.runNextOperation(); } } }); Ext.define('Ext.data.matrix.Slice', { stub: null, constructor: function(side, id) { this.id = id; this.side = side; this.members = {}; }, attach: function(store) { var me = this; Ext.Assert.falsey(me.store, 'Store is already attached'); me.store = store; store.matrix = me; store.on('load', me.onStoreLoad, me, { single: true }); }, changeId: function(newId) { var me = this, oldId = me.id, side = me.side, slices = side.slices, slice = slices[oldId], members = slice.members, index = side.index, otherSlices = side.inverse.slices, assoc, otherId, otherMembers; me.id = newId; slices[newId] = slice; delete slices[oldId]; for (otherId in members) { assoc = members[otherId]; assoc[index] = newId; otherMembers = otherSlices[otherId].members; otherMembers[newId] = otherMembers[oldId]; delete otherMembers[oldId]; } }, onStoreLoad: function(store) { this.update(store.getData().items, 0); }, update: function(recordsOrIds, state) { if (!(recordsOrIds instanceof Array)) { Ext.Error.raise('Only array of records or record ids are supported'); } var me = this, MatrixSlice = Ext.data.matrix.Slice, side = me.side, assocIndex = side.index, length = recordsOrIds.length, id = me.id, members = me.members, otherSide = side.inverse, otherSlices = otherSide.slices, assoc, call, i, item, otherId, otherSlice, record; for (i = 0; i < length; ++i) { call = record = null; item = recordsOrIds[i]; otherId = item.isEntity ? (record = item).id : item; assoc = members[otherId]; if (state < 0 && assoc && assoc[2] === 1) { delete members[otherId]; otherSlice = otherSlices[otherId]; if (otherSlice) { delete otherSlice.members[id]; } call = 1; } else { if (!assoc) { assoc = [ otherId, otherId, state ]; assoc[assocIndex] = id; members[otherId] = assoc; otherSlice = otherSlices[otherId]; if (!otherSlice) { otherSlices[otherId] = otherSlice = new MatrixSlice(otherSide, otherId); } otherSlice.members[id] = assoc; call = 1; } else if (state !== assoc[2] && state !== 0) { assoc[2] = state; otherSlice = otherSlices[otherId]; call = 1; } } if (call) { if (me.notify) { me.notify.call(me.scope, me, otherId, state); } if (otherSlice && otherSlice.notify) { otherSlice.notify.call(otherSlice.scope, otherSlice, id, state); } } } }, destroy: function() { var me = this, store = me.store; if (store) { store.matrix = null; store.un('load', me.onStoreLoad, me); } me.notify = me.scope = me.store = me.side = me.members = null; me.callParent(); } }); Ext.define('Ext.data.matrix.Side', { requires: [ 'Ext.data.matrix.Slice' ], constructor: function(matrix, index, role) { var me = this; me.matrix = matrix; me.index = index; me.role = role; me.slices = {}; }, get: function(id1, id2) { var me = this, slices = me.slices, slice = slices[id1] || (slices[id1] = new Ext.data.matrix.Slice(me, id1)); return (id2 || id2 === 0) ? slice.members[id2] : slice; }, update: function(id1, id2, state) { var slice = this.get(id1); return slice.update(id2, state); }, destroy: function() { var me = this, slices = me.slices, id; for (id in slices) { slices[id].destroy(); } me.inverse = me.matrix = me.role = me.slices = null; me.callParent(); } }); Ext.define('Ext.data.matrix.Matrix', { requires: [ 'Ext.data.matrix.Side' ], constructor: function(session, matrix) { var me = this, association = matrix.isManyToMany ? matrix : session.getSchema().getAssociation(matrix), Side = Ext.data.matrix.Side, left = new Side(me, 0, association.left), right = new Side(me, 1, association.right); Ext.Assert.truthy(association.isManyToMany, 'Association is not many-to-many'); me.association = association; me.session = session; me.left = left; me.right = right; left.inverse = right; right.inverse = left; }, update: function(id1, id2, state) { return this.left.update(id1, id2, state); }, destroy: function() { var me = this; me.left.destroy(); me.right.destroy(); me.association = me.session = me.left = me.right = null; me.callParent(); } }); Ext.define('Ext.data.session.ChangesVisitor', { constructor: function(session) { var me = this, crud; me.session = session; crud = session.getCrudProperties(); me.result = null; me.writerOptions = {}; me.createKey = crud.create; me.readKey = crud.read; me.updateKey = crud.update; me.dropKey = crud.drop; }, onDirtyRecord: function(record) { var me = this, crud = me.crud, created = record.phantom, dropped = record.dropped, updated = !created && !dropped, type = record.$className, prop = (created || dropped) ? 'allDataOptions' : 'partialDataOptions', writerOptions = me.writerOptions, name = record.entityName, options, bucket, entry, result; if (created && dropped) { return false; } crud = created ? me.createKey : (dropped ? me.dropKey : me.updateKey); writerOptions = writerOptions[type] || (writerOptions[type] = {}); if (dropped) { if (!(options = writerOptions.drop)) { writerOptions.drop = options = { all: record.getProxy().getWriter().getWriteAllFields() }; } if (!options.all) { entry = record.id; } } if (!entry) { if (!(options = writerOptions[prop])) { options = record.getProxy().getWriter().getConfig(prop); writerOptions[prop] = options = Ext.Object.chain(options); me.setupOptions(options); } entry = record.getData(options); } result = me.result || (me.result = {}); bucket = result[name] || (result[name] = {}); bucket = bucket[crud] || (bucket[crud] = []); bucket.push(entry); }, setupOptions: function(options) { options.serialize = true; }, onMatrixChange: function(association, id1, id2, state) { var me = this, name = association.left.type, assocName = association.right.role, operation = state < 0 ? me.dropKey : me.createKey, bucket, result; result = me.result || (me.result = {}); bucket = result[name] || (result[name] = {}); bucket = bucket[assocName] || (bucket[assocName] = {}); bucket = bucket[operation] || (bucket[operation] = {}); bucket = bucket[id1] || (bucket[id1] = []); bucket.push(id2); } }); Ext.define('Ext.data.session.ChildChangesVisitor', { extend: 'Ext.data.session.ChangesVisitor', constructor: function() { this.seen = {}; this.callParent(arguments); }, setupOptions: function(options) { this.callParent([ options ]); options.serialize = false; }, onDirtyRecord: function(record) { if (this.callParent(arguments) !== false) { if (!record.$source && (record.dropped || !record.phantom)) { this.readEntity(record); } } }, readEntity: function(record) { var me = this, readKey = me.readKey, name = record.entityName, id = record.id, seen = me.seen, seenKey = name + id, result, bucket; if (seen[seenKey]) { return; } seen[seenKey] = true; result = me.result || (me.result = {}); bucket = result[name] || (result[name] = {}); bucket = bucket[readKey] || (bucket[readKey] = []); bucket.push(Ext.apply({}, record.modified, record.data)); } }); Ext.define('Ext.data.session.BatchVisitor', { map: null, constructor: function(batch) { this.batch = batch; }, getBatch: function(sort) { var map = this.map, batch = this.batch, bucket, entity, name, operation, proxy; if (map) { if (!batch) { batch = new Ext.data.Batch(); } for (name in map) { bucket = map[name]; entity = bucket.entity; proxy = entity.getProxy(); delete bucket.entity; for (operation in bucket) { operation = proxy.createOperation(operation, { records: bucket[operation] }); operation.entityType = entity; batch.add(operation); } } } if (batch && sort !== false) { batch.sort(); } return batch; }, onDirtyRecord: function(record) { var me = this, operation = record.phantom ? 'create' : (record.dropped ? 'destroy' : 'update'), name = record.$className, map = (me.map || (me.map = {})), bucket = (map[name] || (map[name] = { entity: record.self })); bucket = bucket[operation] || (bucket[operation] = []); bucket.push(record); } }); Ext.define('Ext.data.Session', { requires: [ 'Ext.data.schema.Schema', 'Ext.data.Batch', 'Ext.data.matrix.Matrix', 'Ext.data.session.ChangesVisitor', 'Ext.data.session.ChildChangesVisitor', 'Ext.data.session.BatchVisitor' ], isSession: true, config: { schema: 'default', parent: null, autoDestroy: true, crudProperties: { create: 'C', read: 'R', update: 'U', drop: 'D' } }, destroyed: false, crudOperations: [ { type: 'R', entityMethod: 'readEntities' }, { type: 'C', entityMethod: 'createEntities' }, { type: 'U', entityMethod: 'updateEntities' }, { type: 'D', entityMethod: 'dropEntities' } ], crudKeys: { C: 1, R: 1, U: 1, D: 1 }, constructor: function(config) { var me = this; me.data = {}; me.matrices = {}; me.identifierCache = {}; me.recordCreator = me.recordCreator.bind(me); me.initConfig(config); }, destroy: function() { var me = this, matrices = me.matrices, data = me.data, entityName, entities, record, id; for (id in matrices) { matrices[id].destroy(); } for (entityName in data) { entities = data[entityName]; for (id in entities) { record = entities[id].record; if (record) { record.$source = record.session = null; } } } me.recordCreator = me.matrices = me.data = null; me.setSchema(null); me.callParent(); }, adopt: function(record) { var me = this, associations = record.associations, roleName; me.checkModelType(record.self); if (record.session && record.session !== me) { Ext.Error.raise('Record already belongs to an existing session'); } if (record.session !== me) { record.session = me; me.add(record); if (associations) { for (roleName in associations) { associations[roleName].adoptAssociated(record, me); } } } }, commit: function() { var data = this.data, entityName, entities, id, record; for (entityName in data) { entities = data[entityName]; for (id in entities) { record = entities[id].record; if (record) { record.commit(); } } } }, createRecord: function(type, data) { this.checkModelType(type); var Model = type.$isClass ? type : this.getSchema().getEntity(type), parent = this.getParent(), id; if (data && parent) { id = Model.getIdFromData(data); if (parent.peekRecord(Model, id)) { Ext.Error.raise('A parent session already contains an entry for ' + Model.entityName + ': ' + id); } } return new Model(data, this); }, getChanges: function() { var visitor = new Ext.data.session.ChangesVisitor(this); this.visitData(visitor); return visitor.result; }, getChangesForParent: function() { var visitor = new Ext.data.session.ChildChangesVisitor(this); this.visitData(visitor); return visitor.result; }, getRecord: function(type, id, autoLoad) { var me = this, record = me.peekRecord(type, id), Model, parent, parentRec; if (!record) { Model = type.$isClass ? type : me.getSchema().getEntity(type); parent = me.getParent(); if (parent) { parentRec = parent.peekRecord(Model, id); } if (parentRec && !parentRec.isLoading()) { record = parentRec.copy(undefined, me); record.$source = parentRec; } else { record = Model.createWithId(id, null, me); if (autoLoad !== false) { record.load(Ext.isObject(autoLoad) ? autoLoad : undefined); } } } return record; }, getSaveBatch: function(sort) { var visitor = new Ext.data.session.BatchVisitor(); this.visitData(visitor); return visitor.getBatch(sort); }, onInvalidAssociationEntity: function(entityType, id) { Ext.Error.raise('Unable to read association entity: ' + this.getModelIdentifier(entityType, id)); }, onInvalidEntityCreate: function(entityType, id) { Ext.Error.raise('Cannot create, record already not exists: ' + this.getModelIdentifier(entityType, id)); }, onInvalidEntityDrop: function(entityType, id) { Ext.Error.raise('Cannot drop, record does not exist: ' + this.getModelIdentifier(entityType, id)); }, onInvalidEntityRead: function(entityType, id) { Ext.Error.raise('Cannot read, record already not exists: ' + this.getModelIdentifier(entityType, id)); }, onInvalidEntityUpdate: function(entityType, id, dropped) { if (dropped) { Ext.Error.raise('Cannot update, record dropped: ' + this.getModelIdentifier(entityType, id)); } else { Ext.Error.raise('Cannot update, record does not exist: ' + this.getModelIdentifier(entityType, id)); } }, peekRecord: function(type, id, deep) { this.checkModelType(type); var entityType = type.$isClass ? type : this.getSchema().getEntity(type), entityName = entityType.entityName, entry = this.data[entityName], ret, parent; entry = entry && entry[id]; ret = entry && entry.record; if (!ret && deep) { parent = this.getParent(); ret = parent && parent.peekRecord(type, id, deep); } return ret || null; }, save: function() { if (!this.getParent()) { Ext.Error.raise('Cannot commit session, no parent exists'); } var visitor = new Ext.data.session.ChildChangesVisitor(this); this.visitData(visitor); this.getParent().update(visitor.result); }, spawn: function() { return new this.self({ schema: this.getSchema(), parent: this }); }, update: function(data) { var me = this, schema = me.getSchema(), crudOperations = me.crudOperations, len = crudOperations.length, crudKeys = me.crudKeys, entityName, entityType, entityInfo, i, operation, item, associations, key, role, associationData; me.getSchema().processKeyChecks(true); for (entityName in data) { entityType = schema.getEntity(entityName); if (!entityType) { Ext.Error.raise('Invalid entity type: ' + entityName); } entityInfo = data[entityName]; for (i = 0; i < len; ++i) { operation = crudOperations[i]; item = entityInfo[operation.type]; if (item) { me[operation.entityMethod](entityType, item); } } } for (entityName in data) { entityType = schema.getEntity(entityName); associations = entityType.associations; entityInfo = data[entityName]; for (key in entityInfo) { if (crudKeys[key]) { continue; } role = associations[key]; if (!role) { Ext.Error.raise('Invalid association key for ' + entityName + ', "' + key + '"'); } associationData = entityInfo[role.role]; role.processUpdate(me, associationData); } } }, privates: { add: function(record) { var me = this, id = record.id, entry = me.getEntry(record.self, id), associations, roleName; if (entry.record) { Ext.Error.raise('Duplicate id ' + record.id + ' for ' + record.entityName); } entry.record = record; me.registerReferences(record); associations = record.associations; for (roleName in associations) { associations[roleName].checkMembership(me, record); } }, afterErase: function(record) { this.evict(record); }, applySchema: function(schema) { return Ext.data.schema.Schema.get(schema); }, checkModelType: function(name) { if (name.$isClass) { name = name.entityName; } if (!name) { Ext.Error.raise('Unable to use anonymous models in a Session'); } else if (!this.getSchema().getEntity(name)) { Ext.Error.raise('Unknown entity type ' + name); } }, createEntities: function(entityType, items) { var len = items.length, i, data, rec, id; for (i = 0; i < len; ++i) { data = items[i]; id = entityType.getIdFromData(data); rec = this.peekRecord(entityType, id); if (!rec) { rec = this.createRecord(entityType, data); } else { this.onInvalidEntityCreate(entityType, id); } rec.phantom = true; } }, dropEntities: function(entityType, ids) { var len = ids.length, i, rec, id, extractId; if (len) { extractId = Ext.isObject(ids[0]); } for (i = 0; i < len; ++i) { id = ids[i]; if (extractId) { id = entityType.getIdFromData(id); } rec = this.peekRecord(entityType, id); if (rec) { rec.drop(); } else { this.onInvalidEntityDrop(entityType, id); } } }, evict: function(record) { var entityName = record.entityName, entities = this.data[entityName], id = record.id, entry; if (entities) { delete entities[id]; } }, getEntityList: function(entityType, ids) { var len = ids.length, i, id, rec, invalid; for (i = 0; i < len; ++i) { id = ids[i]; rec = this.peekRecord(entityType, id); if (rec) { ids[i] = rec; } else { invalid = true; ids[i] = null; this.onInvalidAssociationEntity(entityType, id); } } if (invalid) { ids = Ext.Array.clean(ids); } return ids; }, getEntry: function(type, id) { if (type.isModel) { id = type.getId(); type = type.self; } var entityType = type.$isClass ? type : this.getSchema().getEntity(type), entityName = entityType.entityName, data = this.data, entry; entry = data[entityName] || (data[entityName] = {}); entry = entry[id] || (entry[id] = {}); return entry; }, getRefs: function(record, role, includeParent) { var entry = this.getEntry(record), refs = entry && entry.refs && entry.refs[role.role], parent = includeParent && this.getParent(), parentRefs, id, rec; if (parent) { parentRefs = parent.getRefs(record, role); if (parentRefs) { for (id in parentRefs) { rec = parentRefs[id]; if ((!refs || !refs[id])) { this.getRecord(rec.self, rec.id); } } refs = entry && entry.refs && entry.refs[role.role]; } } return refs || null; }, getIdentifier: function(entityType) { var parent = this.getParent(), cache, identifier, key, ret; if (parent) { ret = parent.getIdentifier(entityType); } else { cache = this.identifierCache; identifier = entityType.identifier; key = identifier.id || entityType.entityName; ret = cache[key]; if (!ret) { if (identifier.clone) { ret = identifier.clone({ cache: cache }); } else { ret = identifier; } cache[key] = ret; } } return ret; }, getMatrix: function(matrix, preventCreate) { var name = matrix.isManyToMany ? matrix.name : matrix, matrices = this.matrices, ret; ret = matrices[name]; if (!ret && !preventCreate) { ret = matrices[name] = new Ext.data.matrix.Matrix(this, matrix); } return ret || null; }, getMatrixSlice: function(role, id) { var matrix = this.getMatrix(role.association), side = matrix[role.side]; return side.get(id); }, getModelIdentifier: function(entityType, id) { return id + '@' + entityType.entityName; }, onIdChanged: function(record, oldId, newId) { var me = this, entityName = record.entityName, id = record.id, bucket = me.data[entityName], entry = bucket[oldId], associations = record.associations, refs = entry.refs, setNoRefs = me._setNoRefs, association, fieldName, matrix, refId, role, roleName, roleRefs, store; if (bucket[newId]) { Ext.Error.raise('Cannot change ' + entityName + ' id from ' + oldId + ' to ' + newId + ' id already exists'); } delete bucket[oldId]; bucket[newId] = entry; for (roleName in associations) { role = associations[roleName]; if (role.isMany) { store = role.getAssociatedItem(record); if (store) { matrix = store.matrix; if (matrix) { matrix.changeId(newId); } } } } if (refs) { for (roleName in refs) { roleRefs = refs[roleName]; role = associations[roleName]; association = role.association; if (association.isManyToMany) {} else { fieldName = association.field.name; for (refId in roleRefs) { roleRefs[refId].set(fieldName, id, setNoRefs); } } } } me.registerReferences(record, oldId); }, processManyBlock: function(entityType, role, items, processor) { var me = this, id, record, records, store; if (items) { for (id in items) { record = me.peekRecord(entityType, id); if (record) { records = me.getEntityList(role.cls, items[id]); store = role.getAssociatedItem(record); me[processor](role, store, record, records); } else { me.onInvalidAssociationEntity(entityType, id); } } } }, processManyCreate: function(role, store, record, records) { if (store) { store.add(records); } else { record[role.getterName](null, null, records); } }, processManyDrop: function(role, store, record, records) { if (store) { store.remove(records); } }, processManyRead: function(role, store, record, records) { if (store) { store.setRecords(records); } else { record[role.getterName](null, null, records); } }, readEntities: function(entityType, items) { var len = items.length, i, data, rec, id; for (i = 0; i < len; ++i) { data = items[i]; id = entityType.getIdFromData(data); rec = this.peekRecord(entityType, id); if (!rec) { rec = this.createRecord(entityType, data); } else { this.onInvalidEntityRead(entityType, id); } rec.phantom = false; } }, recordCreator: function(data, Model) { var me = this, id = Model.getIdFromData(data), record = me.peekRecord(Model, id, true); if (!record) { record = new Model(data, me); } else { record = me.getRecord(Model, id); } return record; }, registerReferences: function(record, oldId) { var entityName = record.entityName, id = record.id, recordData = record.data, remove = oldId || oldId === 0, entry, i, fk, len, reference, references, refs, roleName; len = (references = record.references).length; for (i = 0; i < len; ++i) { reference = references[i]; fk = recordData[reference.name]; if (fk || fk === 0) { reference = reference.reference; entityName = reference.type; roleName = reference.inverse.role; entry = this.getEntry(reference.cls, fk); refs = entry.refs || (entry.refs = {}); refs = refs[roleName] || (refs[roleName] = {}); refs[id] = record; if (remove) { delete refs[oldId]; } } } }, updateEntities: function(entityType, items) { var len = items.length, i, data, rec, id, modified; if (Ext.isArray(items)) { for (i = 0; i < len; ++i) { data = items[i]; id = entityType.getIdFromData(data); rec = this.peekRecord(entityType, id); if (rec) { rec.set(data); } else { this.onInvalidEntityUpdate(entityType, id); } } } else { for (id in items) { data = items[id]; rec = this.peekRecord(entityType, id); if (rec && !rec.dropped) { modified = rec.set(data); } else { this.onInvalidEntityUpdate(entityType, id, !!rec); } } } }, updateReference: function(record, field, newValue, oldValue) { var reference = field.reference, entityName = reference.type, roleName = reference.inverse.role, id = record.id, entry, refs; if (oldValue || oldValue === 0) { refs = this.getEntry(entityName, oldValue).refs[roleName]; delete refs[id]; } if (newValue || newValue === 0) { entry = this.getEntry(entityName, newValue); refs = entry.refs || (entry.refs = {}); refs = refs[roleName] || (refs[roleName] = {}); refs[id] = record; } }, visitData: function(visitor) { var me = this, data = me.data, matrices = me.matrices, all, assoc, id, id2, matrix, members, name, record, slice, slices, state; me.getSchema().processKeyChecks(true); for (name in data) { all = data[name]; for (id in all) { record = all[id].record; if (record) { if (record.phantom || record.dirty || record.dropped) { if (visitor.onDirtyRecord) { visitor.onDirtyRecord(record); } } else if (visitor.onCleanRecord) { visitor.onCleanRecord(record); } } } } if (visitor.onMatrixChange) { for (name in matrices) { matrix = matrices[name].left; slices = matrix.slices; assoc = matrix.role.association; for (id in slices) { slice = slices[id]; members = slice.members; for (id2 in members) { state = (record = members[id2])[2]; if (state) { visitor.onMatrixChange(assoc, record[0], record[1], state); } } } } } return visitor; }, _setNoRefs: { refs: false } } }); Ext.define('Ext.util.Schedulable', { 'abstract': true, isSchedulable: true, scheduled: false, constructor: function() { this.getScheduler().add(this); }, destroy: function() { var me = this, scheduler = me.getScheduler(); if (scheduler) { scheduler.remove(me); } me.destroyed = true; me.scheduler = null; me.schedule = me.destroy = me.react = Ext.emptyFn; }, getFullName: function() { return this.name || this.id; }, privates: { getScheduler: function() { return this.scheduler; }, schedule: function() { var me = this, scheduler; if (!me.scheduled) { scheduler = me.getScheduler(); if (scheduler) { me.scheduled = true; if (me.onSchedule) { me.onSchedule(); } scheduler.scheduleItem(me); } } }, unschedule: function() { var me = this, scheduler; if (me.scheduled) { scheduler = me.getScheduler(); if (scheduler) { scheduler.unscheduleItem(me); } me.scheduled = false; } }, sort: function() {} } }); Ext.define('Ext.app.bind.BaseBinding', { extend: 'Ext.util.Schedulable', calls: 0, kind: 20, defaultOptions: {}, lastValue: undefined, constructor: function(owner, callback, scope, options) { var me = this; me.options = options; me.owner = owner; me.scope = scope; me.callback = callback; if (!callback) { Ext.Error.raise('Callback is required'); } me.lateBound = Ext.isString(callback); if (options && options.deep) { me.deep = true; } me.callParent(); }, destroy: function() { var me = this, owner = me.owner; me.callParent(); if (owner) { owner.onBindDestroy(); } me.scope = me.callback = me.owner = null; }, privates: { getScheduler: function() { var owner = this.owner; return owner && owner.getScheduler(); }, getSession: function() { var owner = this.owner; return owner.isSession ? owner : owner.getSession(); }, notify: function(value) { var me = this, options = me.options || me.defaultOptions, previous = me.lastValue; if (!me.calls || me.deep || previous !== value || Ext.isArray(value)) { ++me.calls; me.lastValue = value; if (me.lateBound) { me.scope[me.callback](value, previous, me); } else { me.callback.call(me.scope, value, previous, me); } if (options.single) { me.destroy(); } } } } }); Ext.define('Ext.app.bind.Binding', { extend: 'Ext.app.bind.BaseBinding', constructor: function(stub, callback, scope, options) { var me = this; me.callParent([ stub.owner, callback, scope, options ]); me.stub = stub; me.depth = stub.depth; if (!stub.isLoading() && !stub.scheduled) { me.schedule(); } }, destroy: function( fromParent) { var me = this, stub = me.stub; if (stub && !fromParent) { stub.unbind(me); me.stub = null; } me.callParent(); }, bindValidation: function(callback, scope) { var stub = this.stub; return stub && stub.bindValidation(callback, scope); }, bindValidationField: function(callback, scope) { var stub = this.stub; return stub && stub.bindValidationField(callback, scope); }, getFullName: function() { return this.fullName || (this.fullName = '@(' + this.stub.getFullName() + ')'); }, getValue: function() { var me = this, stub = me.stub, ret = stub && stub.getValue(); if (me.transform) { ret = me.transform(ret); } return ret; }, isLoading: function() { var stub = this.stub; return stub && stub.isLoading(); }, isReadOnly: function() { var stub = this.stub, options = this.options; if (!(options && options.twoWay === false)) { if (stub) { return stub.isReadOnly(); } } return true; }, refresh: function() {}, setValue: function(value) { if (this.isReadOnly()) { Ext.Error.raise('Cannot setValue on a readonly binding'); } this.stub.set(value); }, privates: { getDataObject: function() { var stub = this.stub; return stub && stub.getDataObject(); }, getRawValue: function() { var me = this, stub = me.stub, ret = stub && stub.getRawValue(); if (me.transform) { ret = me.transform(ret); } return ret; }, isDescendantOf: function(item) { var stub = this.stub; return stub ? (item === stub) || stub.isDescendantOf(item) : false; }, react: function() { this.notify(this.getValue()); }, schedule: function() { if (!this.stub.scheduled) { this.callParent(); } }, sort: function() { var stub = this.stub; stub.scheduler.sortItem(stub); } } }); Ext.define('Ext.app.bind.AbstractStub', { extend: 'Ext.util.Schedulable', requires: [ 'Ext.app.bind.Binding' ], children: null, depth: 0, generation: 1, kind: 10, parent: null, constructor: function(owner, name) { var me = this; me.owner = owner; me.name = name; me.callParent(); }, destroy: function() { var me = this, children = me.children, bindings = me.bindings, len, i, key; if (bindings) { for (i = 0 , len = bindings.length; i < len; ++i) { bindings[i].destroy(true); } } for (key in children) { children[key].destroy(); } me.callParent(); me.bindings = me.children = me.owner = null; }, add: function(child) { var me = this; (me.children || (me.children = {}))[child.name] = child; child.depth = me.depth + 1; child.parent = me; }, getChild: function(path) { var pathArray = Ext.isString(path) ? path.split('.') : path; if (pathArray && pathArray.length) { return this.descend(pathArray, 0); } return this; }, getFullName: function() { var me = this, name = me.fullName, parent = me.parent, s; if (!name) { name = me.name || me.id; if (parent && (s = parent.getFullName())) { name = ((s.charAt(s.length - 1) !== ':') ? s + '.' : s) + name; } me.fullName = name; } return name; }, getSession: function() { var owner = this.owner; return owner.isSession ? owner : owner.getSession(); }, bind: function(callback, scope, options) { var me = this, binding = new Ext.app.bind.Binding(me, callback, scope, options), bindings = (me.bindings || (me.bindings = [])); binding.depth = me.depth; bindings.push(binding); return binding; }, getValue: function() { return this.isLoading() ? null : this.getRawValue(); }, graft: function(replacement) { var me = this, bindings = me.bindings, name = me.name, i; me.parent = me.bindings = null; me.destroy(); replacement.depth = me.depth; replacement.bindings = bindings; replacement.generation = me.generation + 1; replacement.name = name; replacement.id = me.id; replacement.path = me.path; if (bindings) { for (i = bindings.length; i-- > 0; ) { bindings[i].stub = replacement; } } return replacement; }, isDescendantOf: function(item) { for (var parent = this; parent = parent.parent; ) { if (parent === item) { return true; } } return false; }, onSchedule: function() { for (var i, len, binding, bindings, p = this.parent; p; p = p.parent) { bindings = p.bindings; if (bindings) { for (i = 0 , len = bindings.length; i < len; ++i) { binding = bindings[i]; if (binding.deep && !binding.scheduled) { binding.schedule(); } } } } }, react: function() { var bindings = this.bindings, binding, i, len; if (bindings) { for (i = 0 , len = bindings.length; i < len; ++i) { binding = bindings[i]; if (!binding.scheduled) { binding.schedule(); } } } }, unbind: function(binding) { var bindings = this.bindings; if (bindings && bindings.length) { Ext.Array.remove(bindings, binding); } }, privates: { collect: function() { var children = this.children, bindings = this.bindings, totalCount = 0, count = 0, child, key; if (children) { for (key in children) { child = children[key]; count = child.collect(); if (count === 0) { child.destroy(); delete children[key]; } totalCount += count; } } if (bindings) { totalCount += bindings.length; } return totalCount; }, getScheduler: function() { var owner = this.owner; return owner && owner.getScheduler(); }, sort: function() { var parent = this.parent; if (parent) { this.scheduler.sortItem(parent); } } } }); Ext.define('Ext.app.bind.Stub', { extend: 'Ext.app.bind.AbstractStub', requires: [ 'Ext.app.bind.Binding' ], isStub: true, dirty: true, formula: null, validationKey: 'validation', statics: { trackHadValue: function(value, owner, path, stub) { var children = stub && stub.children, child, key, hadValue; hadValue = value !== undefined; if (!owner.hadValue[path]) { owner.hadValue[path] = hadValue; } if (stub) { stub.hadValue = hadValue; } if (value && (value.constructor === Object || value.isModel)) { if (value.isModel) { value = value.data; } for (key in value) { Ext.app.bind.Stub.trackHadValue(value[key], owner, path + '.' + key, children && children[key]); } } } }, constructor: function(owner, name, parent) { var me = this, path = name; me.callParent([ owner, name ]); me.boundValue = null; if (parent) { parent.add(me); if (!parent.isRootStub) { path = parent.path + '.' + name; } } me.hadValue = owner.hadValue[path]; me.path = path; }, destroy: function() { var me = this, formula = me.formula, parent = me.parent, storeBinding = me.storeBinding; if (formula) { formula.destroy(); } if (storeBinding) { storeBinding.destroy(); } me.detachBound(); me.parentValue = me.formula = me.storeBinding = null; me.callParent(); }, bindValidation: function(callback, scope) { var parent = this.parent; return parent && parent.descend([ this.validationKey, this.name ]).bind(callback, scope); }, bindValidationField: function(callback, scope) { var parent = this.parent, name = this.name, lateBound = typeof callback === 'string', ret; if (parent) { ret = parent.bind(function(value) { var field = null; if (value && value.isModel) { field = value.getField(name); } if (lateBound) { scope[callback](field, null, this); } else { callback.call(scope, field, null, this); } }); } return ret || null; }, descend: function(path, index) { var me = this, children = me.children || (me.children = {}), pos = index || 0, name = path[pos++], ret; if (!(ret = children[name])) { ret = new Ext.app.bind.Stub(me.owner, name, me); } if (pos < path.length) { ret = ret.descend(path, pos); } return ret; }, getChildValue: function(parentData) { var me = this, name = me.name, ret; if (!parentData && !Ext.isString(parentData)) { ret = me.hadValue ? null : undefined; } else { ret = me.inspectValue(parentData); if (!ret) { if (parentData.isEntity) { ret = parentData.data[name]; } else { ret = parentData[name]; } } } return ret; }, getDataObject: function() { var me = this, parentData = me.parent.getDataObject(), name = me.name, ret = parentData ? parentData[name] : null, associations, association; if (!ret && parentData && parentData.isEntity) { associations = parentData.associations; if (associations && name in associations) { ret = parentData[associations[name].getterName](); } } if (!ret || !(ret.$className || Ext.isObject(ret))) { parentData[name] = ret = {}; me.hadValue = me.owner.hadValue[me.path] = true; me.invalidate(true, true); } return ret; }, getRawValue: function() { return this.getChildValue(this.getParentValue()); }, graft: function(replacement) { var me = this, parent = me.parent, children = me.children, name = me.name, i; replacement.parent = parent; replacement.children = children; if (parent) { parent.children[name] = replacement; } if (children) { for (i in children) { children[i].parent = replacement; } } me.children = null; return me.callParent([ replacement ]); }, isLoading: function() { var me = this, parent = me.parent, loading = false, associations, parentValue, value, loadSet; if (parent && !(loading = parent.isLoading())) { parentValue = me.getParentValue(); value = me.inspectValue(parentValue); if (value) { loading = value.isLoading(); } else { if (parentValue && parentValue.isModel) { associations = parentValue.associations; if (!(associations && me.name in associations)) { loading = false; loadSet = true; } } if (!loadSet) { loading = !me.hadValue && me.getRawValue() === undefined; } } } return loading; }, invalidate: function(deep, dirtyOnly) { var me = this, children = me.children, name; me.dirty = true; if (!dirtyOnly && !me.isLoading()) { if (!me.scheduled) { me.schedule(); } } if (deep && children) { for (name in children) { children[name].invalidate(deep, dirtyOnly); } } }, isReadOnly: function() { var formula = this.formula; return !!(formula && !formula.set); }, set: function(value) { var me = this, parent = me.parent, name = me.name, formula = me.formula, parentData, associations, association, formulaStub; if (formula && !formula.settingValue && formula.set) { formula.setValue(value); return; } else if (me.isLinkStub) { formulaStub = me.getLinkFormulaStub(); formula = formulaStub ? formulaStub.formula : null; if (formula) { if (formulaStub.isReadOnly()) { Ext.Error.raise('Cannot setValue on a readonly formula'); } formula.setValue(value); return; } } parentData = parent.getDataObject(); if (parentData.isEntity) { associations = parentData.associations; if (associations && (name in associations)) { association = associations[name]; parentData[association.setterName](value); me.invalidate(true); } else { parentData.set(name, value); } } else if ((value && value.constructor === Object) || value !== parentData[name]) { if (!me.setByLink(value)) { if (value === undefined) { delete parentData[name]; } else { parentData[name] = value; Ext.app.bind.Stub.trackHadValue(value, me.owner, me.path, me); } me.inspectValue(parentData); me.invalidate(true); } } }, onStoreLoad: function() { this.invalidate(true); }, afterLoad: function(record) { this.invalidate(true); }, afterCommit: function(record) { this.afterEdit(record, null); }, afterEdit: function(record, modifiedFieldNames) { var children = this.children, len = modifiedFieldNames && modifiedFieldNames.length, associations = record.associations, key, i, child, scheduled; if (children) { if (len) { for (i = 0; i < len; ++i) { child = children[modifiedFieldNames[i]]; if (child) { child.invalidate(); } } } else { for (key in children) { if (!(associations && key in associations)) { children[key].invalidate(); } } } } this.invalidate(); }, afterReject: function(record) { this.afterEdit(record, null); }, setByLink: function(value) { var me = this, n = 0, i, link, path, stub; for (stub = me; stub; stub = stub.parent) { if (stub.isLinkStub) { link = stub; if (n) { for (path = [] , i = 0 , stub = me; stub !== link; stub = stub.parent) { ++i; path[n - i] = stub.name; } } break; } ++n; } if (!link || !(stub = link.getTargetStub())) { return false; } if (path) { stub = stub.descend(path); } stub.set(value); return true; }, setFormula: function(formula) { var me = this, oldFormula = me.formula; if (oldFormula) { oldFormula.destroy(); } me.formula = new Ext.app.bind.Formula(me, formula); }, react: function() { var me = this, bound = this.boundValue, children = me.children, generation; if (bound) { if (bound.isValidation) { bound.refresh(); generation = bound.generation; if (me.lastValidationGeneration === generation) { return; } me.lastValidationGeneration = generation; } else if (bound.isModel) { if (children && children[me.validationKey]) { bound.isValid(); } } else if (bound.isStore) { if (bound.isLoading() && !bound.loadCount) { return; } } } this.callParent(); }, privates: { collect: function() { var me = this, result = me.callParent(), storeBinding = me.storeBinding ? 1 : 0, formula = me.formula ? 1 : 0; return result + storeBinding + formula; }, getLinkFormulaStub: function() { var stub = this; while (stub.isLinkStub) { stub = stub.binding.stub; } return stub.formula ? stub : null; }, getParentValue: function() { var me = this; if (me.dirty) { me.parentValue = me.parent.getValue(); me.dirty = false; } return me.parentValue; }, setStore: function(storeBinding) { this.storeBinding = storeBinding; }, inspectValue: function(parentData) { var me = this, name = me.name, current = me.boundValue, boundValue = null, associations, raw, changed, associatedEntity; if (parentData && parentData.isEntity) { associations = parentData.associations; if (associations && (name in associations)) { boundValue = parentData[associations[name].getterName](); if (boundValue && boundValue.isStore) { boundValue.$associatedStore = true; } } else if (name === me.validationKey) { boundValue = parentData.getValidation(); me.lastValidationGeneration = null; } } else if (parentData) { raw = parentData[name]; if (raw && (raw.isModel || raw.isStore)) { boundValue = raw; } } changed = current !== boundValue; if (changed) { if (current) { me.detachBound(); } if (boundValue) { if (boundValue.isModel) { boundValue.join(me); } else { associatedEntity = boundValue.associatedEntity; if (associatedEntity && !associatedEntity.phantom && !boundValue.complete && !boundValue.hasPendingLoad()) { boundValue.load(); } boundValue.on('load', me.onStoreLoad, me, { single: true }); } } me.boundValue = boundValue; } return boundValue; }, detachBound: function() { var me = this, current = me.boundValue; if (current) { if (current.isModel) { current.unjoin(me); } else { current.un('load', me.onStoreLoad, me); } } }, sort: function() { var me = this, formula = me.formula, scheduler = me.scheduler, storeBinding = me.storeBinding; me.callParent(); if (storeBinding) { scheduler.sortItem(storeBinding); } if (formula) { scheduler.sortItem(formula); } } } }); Ext.define('Ext.app.bind.LinkStub', { extend: 'Ext.app.bind.Stub', isLinkStub: true, binding: null, destroy: function() { var me = this, binding = me.binding, owner = me.owner; if (binding) { me.binding = null; binding.destroy(); if (owner) { delete owner.linkData[me.name]; } } me.target = null; me.callParent(); }, getFullName: function() { var me = this; return me.fullName || (me.fullName = '(' + me.callParent() + ' -> ' + me.binding.getFullName() + ')'); }, getDataObject: function() { var binding = this.binding; return binding && binding.getDataObject(); }, getRawValue: function() { var binding = this.binding; return binding && binding.getRawValue(); }, getValue: function() { var binding = this.binding; return binding && binding.getValue(); }, getTargetStub: function() { var binding = this.binding; return binding && binding.stub; }, isLoading: function() { var binding = this.binding; return binding ? binding.isLoading() : false; }, link: function(bindDescriptor, target) { var me = this, binding = me.binding; if (binding) { binding.destroy(); } target = me.target = target || me.owner; me.linkDescriptor = bindDescriptor; me.binding = target.bind(bindDescriptor, me.onChange, me); me.binding.deep = true; }, onChange: function() { this.invalidate(true); }, react: function() { var me = this, linkData = me.owner.linkData; linkData[me.name] = me.getValue(); me.callParent(); }, privates: { collect: function() { var me = this, result = me.callParent(), binding = me.binding ? 1 : 0; return result + binding; }, sort: function() { var binding = this.binding; if (binding) { this.scheduler.sortItem(binding); } } } }); Ext.define('Ext.app.bind.RootStub', { extend: 'Ext.app.bind.AbstractStub', requires: [ 'Ext.app.bind.LinkStub', 'Ext.app.bind.Stub' ], isRootStub: true, depth: 0, createRootChild: function(name, direct) { var me = this, owner = me.owner, ownerData = owner.getData(), children = me.children, previous = children && children[name], parentStub = previous ? null : me, parentVM, stub; if (direct || ownerData.hasOwnProperty(name) || !(parentVM = owner.getParent())) { stub = new Ext.app.bind.Stub(owner, name, parentStub); } else { stub = new Ext.app.bind.LinkStub(owner, name, previous ? null : parentStub); stub.link('{' + name + '}', parentVM); } if (previous) { previous.graft(stub); } return stub; }, createStubChild: function(name) { return this.createRootChild(name, true); }, descend: function(path, index) { var me = this, children = me.children, pos = index || 0, name = path[pos++], ret = (children && children[name]) || me.createRootChild(name); if (pos < path.length) { ret = ret.descend(path, pos); } return ret; }, getFullName: function() { return this.fullName || (this.fullName = this.owner.id + ':'); }, getDataObject: function() { return this.owner.data; }, getRawValue: function() { return this.owner.data; }, getValue: function() { return this.owner.data; }, isDescendantOf: function() { return false; }, isLoading: function() { return false; }, set: function(value) { if (!value || value.constructor !== Object) { Ext.Error.raise('Only an object can be set at the root'); } var me = this, children = me.children || (me.children = {}), owner = me.owner, data = owner.data, parentVM = owner.getParent(), linkStub, stub, v, key; for (key in value) { if (key.indexOf('.') >= 0) { Ext.Error.raise('Value names cannot contain dots'); } if ((v = value[key]) !== undefined) { if (!(stub = children[key])) { stub = new Ext.app.bind.Stub(owner, key, me); } else if (stub.isLinkStub) { if (!stub.getLinkFormulaStub()) { linkStub = stub; stub = new Ext.app.bind.Stub(owner, key); linkStub.graft(stub); } } stub.set(v); } else if (data.hasOwnProperty(key)) { delete data[key]; stub = children[key]; if (stub && !stub.isLinkStub && parentVM) { stub = me.createRootChild(key); } stub.invalidate(true); } } }, schedule: Ext.emptyFn, unschedule: Ext.emptyFn }); Ext.define('Ext.app.bind.Multi', { extend: 'Ext.app.bind.BaseBinding', isMultiBinding: true, missing: 1, deep: true, constructor: function(descriptor, owner, callback, scope, options) { var me = this, trackStatics = options && options.trackStatics; me.callParent([ owner, callback, scope, options ]); me.bindings = []; me.literal = descriptor.$literal; if (descriptor.constructor === Object) { if (trackStatics) { me.staticKeys = []; } me.addObject(descriptor, me.lastValue = {}, me.staticKeys); } else { me.addArray(descriptor, me.lastValue = []); } if (!--me.missing && !me.scheduled) { me.schedule(); } }, destroy: function() { var me = this; me.bindings = Ext.destroy(me.bindings); me.callParent(); }, add: function(descriptor, data, property) { var me = this, owner = me.owner, bindings = me.bindings, method = me.literal ? (descriptor.reference ? 'bindEntity' : 'bindExpression') : 'bind', binding, depth; ++me.missing; binding = owner[method](descriptor, function(value) { data[property] = value; if (binding.calls === 1) { --me.missing; } if (!me.missing && !me.scheduled) { me.schedule(); } }, me, null); depth = binding.depth; if (!bindings.length || depth < me.depth) { me.depth = depth; } bindings.push(binding); return !this.isBindingStatic(binding); }, addArray: function(multiBindDescr, array) { var me = this, n = multiBindDescr.length, hasDynamic = false, dynamic, b, i; for (i = 0; i < n; ++i) { b = multiBindDescr[i]; if (b && (b.reference || Ext.isString(b))) { dynamic = me.add(b, array, i); } else if (Ext.isArray(b)) { dynamic = me.addArray(b, array[i] = []); } else if (b && b.constructor === Object) { dynamic = me.addObject(b, array[i] = {}); } else { array[i] = b; dynamic = false; } hasDynamic = hasDynamic || dynamic; } return hasDynamic; }, addObject: function(multiBindDescr, object, staticKeys) { var me = this, hasDynamic = false, dynamic, b, name; for (name in multiBindDescr) { b = multiBindDescr[name]; if (b && (b.reference || Ext.isString(b))) { dynamic = me.add(b, object, name); } else if (Ext.isArray(b)) { dynamic = me.addArray(b, object[name] = []); } else if (b && b.constructor === Object) { dynamic = me.addObject(b, object[name] = {}); } else { object[name] = b; dynamic = false; } if (staticKeys && !dynamic) { staticKeys.push(name); } hasDynamic = hasDynamic || dynamic; } return hasDynamic; }, getFullName: function() { var me = this, fullName = me.fullName, bindings = me.bindings, length = bindings.length, i; if (!fullName) { fullName = '@['; for (i = 0; i < length; ++i) { if (i) { fullName += ','; } fullName += bindings[i].getFullName(); } fullName += ']'; me.fullName = fullName; } return fullName; }, getRawValue: function() { return this.lastValue; }, isDescendantOf: function() { return false; }, isLoading: function() { for (var bindings = this.bindings, n = bindings.length; n-- > 0; ) { if (bindings[n].isLoading()) { return true; } } return false; }, isBindingStatic: function(binding) { return binding.isTemplateBinding && binding.isStatic; }, isStatic: function() { var bindings = this.bindings, len = bindings.length, i, binding; for (i = 0; i < len; ++i) { binding = bindings[i]; if (!this.isBindingStatic(binding)) { return false; } } return true; }, pruneStaticKeys: function() { var value = Ext.apply({}, this.lastValue), keys = this.staticKeys, len = keys.length, i; for (i = 0; i < len; ++i) { delete value[keys[i]]; } return value; }, react: function() { this.notify(this.lastValue); }, refresh: function() {}, privates: { sort: function() { this.scheduler.sortItems(this.bindings); } } }); Ext.define('Ext.app.bind.Formula', { extend: 'Ext.util.Schedulable', requires: [ 'Ext.util.LruCache' ], statics: { getFormulaParser: function(name) { var cache = this.formulaCache, parser, s; if (!cache) { cache = this.formulaCache = new Ext.util.LruCache({ maxSize: 20 }); } parser = cache.get(name); if (!parser) { s = '[^\\.a-z0-9_]' + name + '\\(\\s*([\'"])(.*?)\\1\\s*\\)'; parser = new RegExp(s, 'gi'); cache.add(name, parser); } return parser; } }, isFormula: true, calculation: null, explicit: false, set: null, single: false, argumentNamesRe: /^function\s*\(\s*([^,\)\s]+)/, constructor: function(stub, formula) { var me = this, owner = stub.owner, bindTo, expressions, getter, options; me.owner = owner; me.stub = stub; me.callParent(); if (formula instanceof Function) { me.get = getter = formula; } else { me.get = getter = formula.get; me.set = formula.set; expressions = formula.bind; if (formula.single) { me.single = formula.single; } if (expressions) { bindTo = expressions.bindTo; if (bindTo) { options = Ext.apply({}, expressions); delete options.bindTo; expressions = bindTo; } } } if (!getter) { Ext.Error.raise('Must specify a getter method for a formula'); } if (expressions) { me.explicit = true; } else { expressions = getter.$expressions || me.parseFormula(getter); } me.binding = owner.bind(expressions, me.onChange, me, options); }, destroy: function() { var me = this, binding = me.binding, stub = me.stub; if (binding) { binding.destroy(); me.binding = null; } if (stub) { stub.formula = null; } me.callParent(); me.getterFn = me.owner = null; }, getFullName: function() { return this.fullName || (this.fullName = this.stub.getFullName() + '=' + this.callParent() + ')'); }, getRawValue: function() { return this.calculation; }, onChange: function() { if (!this.scheduled) { this.schedule(); } }, parseFormula: function(formula) { var str = formula.toString(), expressions = { $literal: true }, match, getterProp, formulaRe, expr; match = this.argumentNamesRe.exec(str); getterProp = match ? match[1] : 'get'; formulaRe = Ext.app.bind.Formula.getFormulaParser(getterProp); while ((match = formulaRe.exec(str))) { expr = match[2]; expressions[expr] = expr; } expressions.$literal = true; formula.$expressions = expressions; return expressions; }, react: function() { var me = this, owner = me.owner, data = me.binding.lastValue, getterFn = me.getterFn, arg; if (me.explicit) { arg = data; } else { arg = owner.getFormulaFn(data); } me.settingValue = true; me.stub.set(me.calculation = me.get.call(owner, arg)); me.settingValue = false; if (me.single) { me.destroy(); } }, setValue: function(value) { this.set.call(this.stub.owner, value); }, privates: { getScheduler: function() { var owner = this.owner; return owner && owner.getScheduler(); }, sort: function() { var me = this, binding = me.binding; if (!binding.destroyed) { me.scheduler.sortItem(binding); } } } }); Ext.define('Ext.app.bind.Template', { requires: [ 'Ext.util.Format' ], numberRe: /^(?:\d+(?:\.\d*)?)$/, stringRe: /^(?:["][^"]*["])$/, tokenRe: /\{[!]?(?:(?:(\d+)|([a-z_][\w\-\.]*))(?::([a-z_\.]+)(?:\(([^\)]*?)?\))?)?)\}/gi, formatRe: /^([a-z_]+)(?:\(([^\)]*?)?\))?$/i, buffer: null, slots: null, tokens: null, constructor: function(text) { var me = this, initters = me._initters, name; me.text = text; for (name in initters) { me[name] = initters[name]; } }, _initters: { apply: function(values, scope) { return this.parse().apply(values, scope); }, getTokens: function() { return this.parse().getTokens(); } }, apply: function(values, scope) { var me = this, slots = me.slots, buffer = me.buffer, length = slots.length, i, slot, value; for (i = 0; i < length; ++i) { slot = slots[i]; if (slot) { if ((value = values[slot.pos]) == null) { value = ''; } if (slot.not) { value = !value; } if (slot.format) { value = slot.format(value, scope); } buffer[i] = value; } } return buffer.join(''); }, getTokens: function() { return this.tokens; }, parse: function() { var me = this, text = me.text, buffer = [], slots = [], tokens = [], tokenMap = {}, last = 0, tokenRe = me.tokenRe, pos = 0, fmt, i, length, match, s, slot, token; for (i in me._initters) { delete me[i]; } me.buffer = buffer; me.slots = slots; me.tokens = tokens; while ((match = tokenRe.exec(text))) { length = match.index - last; if (length) { buffer[pos++] = text.substring(last, last + length); last += length; } last += (s = match[0]).length; slot = { fmt: (fmt = match[3] || null), index: match[1] ? parseInt(match[1], 10) : null, not: s.charAt(1) === '!', token: match[2] || null }; token = slot.token || String(slot.index); if (token in tokenMap) { slot.pos = tokenMap[token]; } else { tokenMap[token] = slot.pos = tokens.length; tokens.push(token); } if (fmt) { if (fmt.substring(0, 5) === 'this.') { slot.fmt = fmt.substring(5); } else { if (!(fmt in Ext.util.Format)) { Ext.Error.raise('Invalid format specified: "' + fmt + '"'); } slot.scope = Ext.util.Format; } me.parseArgs(match[4], slot); } slots[pos++] = slot; } if (last < text.length) { buffer[pos++] = text.substring(last); } return me; }, parseArgs: function(argsString, slot) { var me = this, numberRe = me.numberRe, stringRe = me.stringRe, arg, args, i, length; if (!argsString) { args = []; } else if (argsString.indexOf(',') < 0) { args = [ argsString ]; } else { args = argsString.split(','); } slot = slot || {}; length = args.length; slot.args = args; for (i = 0; i < length; ++i) { arg = args[i]; if (arg === 'true') { args[i] = true; } else if (arg === 'false') { args[i] = false; } else if (arg === 'null') { args[i] = null; } else if (numberRe.test(arg)) { args[i] = parseFloat(arg); } else if (stringRe.test(arg)) { args[i] = arg.substring(1, arg.length - 1); } else { slot.fn = Ext.functionFactory('return [' + argsString + '];'); slot.format = me._formatEval; break; } } if (!slot.format) { args.unshift(0); slot.format = me._formatArgs; } return slot; }, parseFormat: function(fmt) { var me = this, match = me.formatRe.exec(fmt), slot = { fmt: fmt, scope: Ext.util.Format }, args; if (!match) { Ext.Error.raise('Invalid format syntax: "' + slot + '"'); } args = match[2]; if (args) { slot.fmt = match[1]; me.parseArgs(args, slot); } else { slot.args = [ 0 ]; slot.format = me._formatArgs; } return slot; }, _formatArgs: function(value, scope) { scope = this.scope || scope; this.args[0] = value; return scope[this.fmt].apply(scope, this.args); }, _formatEval: function(value, scope) { var args = this.fn(); args.unshift(value); scope = this.scope || scope; return scope[this.fmt].apply(scope, args); } }); Ext.define('Ext.app.bind.TemplateBinding', { extend: 'Ext.app.bind.BaseBinding', requires: [ 'Ext.app.bind.Multi', 'Ext.app.bind.Template' ], isTemplateBinding: true, lastValue: undefined, value: undefined, constructor: function(template, owner, callback, scope, options) { var me = this, tpl = new Ext.app.bind.Template(template), tokens = tpl.getTokens(); me.callParent([ owner, callback, scope, options ]); me.tpl = tpl; me.tokens = tokens; tokens.$literal = true; if (tokens.length) { me.multiBinding = new Ext.app.bind.Multi(tokens, owner, me.onBindData, me); } else { me.isStatic = true; me.onData(tpl.text); } }, destroy: function() { var me = this; Ext.destroy(me.multiBinding); me.tpl = me.multiBinding = null; me.callParent(); }, getFullName: function() { var multi = this.multiBinding; return this.fullName || (this.fullName = '$' + (multi ? multi.getFullName() : this.callParent())); }, getRawValue: function() { return this.value; }, getTemplateScope: function() { return null; }, isDescendantOf: function() { return false; }, isLoading: function() { var multi = this.multiBinding; return multi ? multi.isLoading() : false; }, onBindData: function(data) { this.onData(this.tpl.apply(data, this.getTemplateScope())); }, onData: function(value) { var me = this, lastValue = me.value; if (lastValue !== (me.value = value)) { me.lastValue = lastValue; me.schedule(); } }, react: function() { this.notify(this.value); }, refresh: function() { var multi = this.multiBinding; if (multi) { multi.refresh(); } }, privates: { sort: function() { var multi = this.multiBinding; if (multi) { this.scheduler.sortItem(multi); } } } }); Ext.define('Ext.data.ChainedStore', { extend: 'Ext.data.AbstractStore', alias: 'store.chained', config: { source: null, remoteFilter: false, remoteSort: false }, mixins: [ 'Ext.data.LocalStore' ], constructor: function() { this.callParent(arguments); this.getData().addObserver(this); }, blockLoad: Ext.emptyFn, unblockLoad: Ext.emptyFn, updateRemoteFilter: function(remoteFilter, oldRemoteFilter) { if (remoteFilter) { Ext.Error.raise('Remote filtering cannot be used with chained stores.'); } this.callParent([ remoteFilter, oldRemoteFilter ]); }, updateRemoteSort: function(remoteSort, oldRemoteSort) { if (remoteSort) { Ext.Error.raise('Remote sorting cannot be used with chained stores.'); } this.callParent([ remoteSort, oldRemoteSort ]); }, remove: function() { var source = this.getSource(); return source.remove.apply(source, arguments); }, getData: function() { var me = this, data = me.data; if (!data) { me.data = data = me.constructDataCollection(); } return data; }, getSession: function() { return this.getSource().getSession(); }, applySource: function(source) { if (source) { var original = source, s; source = Ext.data.StoreManager.lookup(source); if (!source) { s = 'Invalid source {0}specified for Ext.data.ChainedStore'; s = Ext.String.format(s, typeof original === 'string' ? '"' + original + '" ' : ''); Ext.Error.raise(s); } } return source; }, updateSource: function(source, oldSource) { var me = this, data; if (oldSource) { oldSource.removeObserver(me); } if (source) { data = me.getData(); data.setSource(source.getData()); if (!me.isInitializing) { me.fireEvent('refresh', me); me.fireEvent('datachanged', me); } source.addObserver(me); } }, getModel: function() { return this.getSource().getModel(); }, getProxy: function() { return null; }, onCollectionAdd: function(collection, info) { var me = this, records = info.items, lastChunk = !info.next; if (me.ignoreCollectionAdd) { return; } me.fireEvent('add', me, records, info.at); if (lastChunk) { me.fireEvent('datachanged', me); } }, onCollectionItemChange: function(collection, info) { var me = this, record = info.item, modifiedFieldNames = info.modified || null, type = info.meta; me.onUpdate(record, type, modifiedFieldNames, info); me.fireEvent('update', me, record, type, modifiedFieldNames, info); }, onUpdate: Ext.emptyFn, onCollectionRemove: function(collection, info) { var me = this, records = info.items, lastChunk = !info.next; if (me.ignoreCollectionRemove) { return; } me.fireEvent('remove', me, records, info.at, false); if (lastChunk) { me.fireEvent('datachanged', me); } }, onSourceBeforeLoad: function(source, operation) { this.fireEvent('beforeload', this, operation); }, onSourceAfterLoad: function(source, records, successful, operation) { this.fireEvent('load', this, records, successful, operation); }, onFilterEndUpdate: function() { this.callParent(arguments); this.callObservers('Filter'); }, onSourceBeforePopulate: function() { this.ignoreCollectionAdd = true; this.callObservers('BeforePopulate'); }, onSourceAfterPopulate: function() { var me = this; me.ignoreCollectionAdd = false; me.fireEvent('datachanged', me); me.fireEvent('refresh', me); this.callObservers('AfterPopulate'); }, onSourceBeforeClear: function() { this.ignoreCollectionRemove = true; this.callObservers('BeforeClear'); }, onSourceAfterClear: function() { this.ignoreCollectionRemove = false; this.callObservers('AfterClear'); }, onSourceBeforeRemoveAll: function() { this.ignoreCollectionRemove = true; this.callObservers('BeforeRemoveAll'); }, onSourceAfterRemoveAll: function(source, silent) { var me = this; me.ignoreCollectionRemove = false; if (!silent) { me.fireEvent('clear', me); me.fireEvent('datachanged', me); } this.callObservers('AfterRemoveAll', [ silent ]); }, onSourceFilter: function() { var me = this; me.fireEvent('refresh', me); me.fireEvent('datachanged', me); }, hasPendingLoad: function() { return this.getSource().hasPendingLoad(); }, isLoaded: function() { return this.getSource().isLoaded(); }, isLoading: function() { return this.getSource().isLoading(); }, onDestroy: function() { var me = this; me.observers = null; me.setSource(null); me.getData().destroy(true); me.data = null; }, privates: { isMoving: function() { var source = this.getSource(); return source.isMoving ? source.isMoving.apply(source, arguments) : false; }, loadsSynchronously: function() { return this.getSource().loadsSynchronously(); } } }); Ext.define('Ext.app.ViewModel', { mixins: [ 'Ext.mixin.Factoryable', 'Ext.mixin.Identifiable' ], requires: [ 'Ext.util.Scheduler', 'Ext.data.Session', 'Ext.app.bind.RootStub', 'Ext.app.bind.LinkStub', 'Ext.app.bind.Multi', 'Ext.app.bind.Formula', 'Ext.app.bind.TemplateBinding', 'Ext.data.ChainedStore' ], alias: 'viewmodel.default', isViewModel: true, factoryConfig: { name: 'viewModel' }, destroyed: false, collectTimeout: 100, expressionRe: /^(?:\{[!]?(?:(\d+)|([a-z_][\w\-\.]*))\})$/i, $configStrict: false, config: { data: true, formulas: { $value: null, merge: function(newValue, currentValue, target, mixinClass) { return this.mergeNew(newValue, currentValue, target, mixinClass); } }, links: null, parent: null, root: true, scheduler: null, schema: 'default', session: null, stores: null, view: null }, constructor: function(config) { this.hadValue = {}; this.initConfig(config); }, destroy: function() { var me = this, scheduler = me._scheduler, stores = me.storeInfo, parent = me.getParent(), task = me.collectTask, children = me.children, key, store, autoDestroy; me.destroying = true; if (task) { task.cancel(); me.collectTask = null; } if (children) { for (key in children) { children[key].destroy(); } } if (stores) { for (key in stores) { store = stores[key]; autoDestroy = store.autoDestroy; if (autoDestroy || (!store.$wasInstance && autoDestroy !== false)) { store.destroy(); } Ext.destroy(store.$binding); } } if (parent) { parent.unregisterChild(me); } me.getRoot().destroy(); if (scheduler && scheduler.$owner === me) { scheduler.$owner = null; scheduler.destroy(); } me.hadValue = me.children = me.storeInfo = me._session = me._view = me._scheduler = me._root = me._parent = me.formulaFn = me.$formulaData = null; me.callParent(); }, bind: function(descriptor, callback, scope, options) { var me = this, binding; scope = scope || me; if (!options && descriptor.bindTo !== undefined && !Ext.isString(descriptor)) { options = descriptor; descriptor = options.bindTo; } if (!Ext.isString(descriptor)) { binding = new Ext.app.bind.Multi(descriptor, me, callback, scope, options); } else if (me.expressionRe.test(descriptor)) { descriptor = descriptor.substring(1, descriptor.length - 1); binding = me.bindExpression(descriptor, callback, scope, options); } else { binding = new Ext.app.bind.TemplateBinding(descriptor, me, callback, scope, options); } return binding; }, getSession: function() { var me = this, session = me._session, parent; if (!session && (parent = me.getParent())) { me.setSession(session = parent.getSession()); } return session || null; }, getStore: function(key) { var storeInfo = this.storeInfo, store; if (storeInfo) { store = storeInfo[key]; } return store || null; }, linkTo: function(key, reference) { var me = this, stub = me.getStub(key), create, id, modelType, linkStub, rec; if (stub.depth - me.getRoot().depth > 1) { Ext.Error.raise('Links can only be at the top-level: "' + key + '"'); } if (reference.isModel) { reference = { type: reference.entityName, id: reference.id }; } modelType = reference.type || reference.reference; create = reference.create; if (modelType) { id = reference.id; if (!reference.create && Ext.isEmpty(id)) { Ext.Error.raise('No id specified. To create a phantom model, specify "create: true" as part of the reference.'); } if (create) { id = undefined; } rec = me.getRecord(modelType, id); if (Ext.isObject(create)) { rec.set(create); rec.commit(); rec.phantom = true; } stub.set(rec); } else { if (!stub.isLinkStub) { linkStub = new Ext.app.bind.LinkStub(me, stub.name); stub.graft(linkStub); stub = linkStub; } stub.link(reference); } }, notify: function() { this.getScheduler().notify(); }, get: function(path) { return this.getStub(path).getValue(); }, set: function(path, value) { var me = this, obj, stub; me.getData(); if (value === undefined && path && path.constructor === Object) { stub = me.getRoot(); value = path; } else if (path && path.indexOf('.') < 0) { obj = {}; obj[path] = value; value = obj; stub = me.getRoot(); } else { stub = me.getStub(path); } stub.set(value); }, privates: { registerChild: function(child) { var children = this.children; if (!children) { this.children = children = {}; } children[child.getId()] = child; }, unregisterChild: function(child) { var children = this.children; if (!this.destroying && children) { delete children[child.getId()]; } }, getRecord: function(type, id) { var session = this.getSession(), Model = type, hasId = id !== undefined, record; if (session) { if (hasId) { record = session.getRecord(type, id); } else { record = session.createRecord(type); } } else { if (!Model.$isClass) { Model = this.getSchema().getEntity(Model); if (!Model) { Ext.Error.raise('Invalid model name: ' + type); } } if (hasId) { record = Model.createWithId(id); record.load(); } else { record = new Model(); } } return record; }, notFn: function(v) { return !v; }, bindExpression: function(descriptor, callback, scope, options) { var ch = descriptor.charAt(0), not = (ch === '!'), path = not ? descriptor.substring(1) : descriptor, stub = this.getStub(path), binding; binding = stub.bind(callback, scope, options); if (not) { binding.transform = this.notFn; } return binding; }, applyScheduler: function(scheduler) { if (scheduler && !scheduler.isInstance) { scheduler = new Ext.util.Scheduler(scheduler); scheduler.$owner = this; } return scheduler; }, getScheduler: function() { var me = this, scheduler = me._scheduler, parent, session; if (!scheduler) { if (!(parent = me.getParent())) { scheduler = new Ext.util.Scheduler({ preSort: 'kind,-depth' }); scheduler.$owner = me; } else { scheduler = parent.getScheduler(); } me.setScheduler(scheduler); } return scheduler; }, getStub: function(bindDescr) { var root = this.getRoot(); return bindDescr ? root.getChild(bindDescr) : root; }, collect: function() { var me = this, parent = me.getParent(), task = me.collectTask; if (parent) { parent.collect(); return; } if (!task) { task = me.collectTask = new Ext.util.DelayedTask(me.doCollect, me); } if (me.collectTimeout === 0) { me.doCollect(); } else { task.delay(me.collectTimeout); } }, doCollect: function() { var children = this.children, key; if (children) { for (key in children) { children[key].doCollect(); } } this.getRoot().collect(); }, onBindDestroy: function() { var me = this, parent; if (me.destroying) { return; } parent = me.getParent(); if (parent) { parent.onBindDestroy(); } else { me.collect(); } }, applyData: function(newData, data) { var me = this, linkData, parent; me.getSession(); if (!data) { parent = me.getParent(); me.linkData = linkData = parent ? Ext.Object.chain(parent.getData()) : {}; me.data = me._data = Ext.Object.chain(linkData); } if (newData && newData.constructor === Object) { me.getRoot().set(newData); } }, applyParent: function(parent) { if (parent) { parent.registerChild(this); } return parent; }, applyStores: function(stores) { var me = this, root = me.getRoot(), key, cfg, storeBind, stub, listeners, isStatic; me.storeInfo = {}; me.listenerScopeFn = function() { return me.getView().getInheritedConfig('defaultListenerScope'); }; for (key in stores) { cfg = stores[key]; if (cfg.isStore) { cfg.$wasInstance = true; me.setupStore(cfg, key); continue; } else if (Ext.isString(cfg)) { cfg = { source: cfg }; } else { cfg = Ext.apply({}, cfg); } listeners = cfg.listeners; delete cfg.listeners; storeBind = me.bind(cfg, me.onStoreBind, me, { trackStatics: true }); if (storeBind.isStatic()) { storeBind.destroy(); me.createStore(key, cfg, listeners); } else { storeBind.$storeKey = key; storeBind.$listeners = listeners; stub = root.createStubChild(key); stub.setStore(storeBind); } } }, onStoreBind: function(cfg, oldValue, binding) { var info = this.storeInfo, key = binding.$storeKey, store = info[key], proxy; if (!store) { this.createStore(key, cfg, binding.$listeners, binding); } else { cfg = Ext.merge({}, binding.pruneStaticKeys()); proxy = cfg.proxy; delete cfg.type; delete cfg.model; delete cfg.fields; delete cfg.proxy; delete cfg.listeners; if (proxy) { delete proxy.reader; delete proxy.writer; store.getProxy().setConfig(proxy); } store.blockLoad(); store.setConfig(cfg); store.unblockLoad(true); } }, createStore: function(key, cfg, listeners, binding) { var session = this.getSession(), store; cfg = Ext.apply({}, cfg); if (cfg.session) { cfg.session = session; } if (cfg.source) { cfg.type = cfg.type || 'chained'; } cfg.listeners = listeners; store = Ext.Factory.store(cfg); store.$binding = binding; this.setupStore(store, key); }, setupStore: function(store, key) { store.resolveListenerScope = this.listenerScopeFn; this.storeInfo[key] = store; this.set(key, store); }, applyFormulas: function(formulas) { var me = this, root = me.getRoot(), name, stub; me.getData(); for (name in formulas) { if (name.indexOf('.') >= 0) { Ext.Error.raise('Formula names cannot contain dots: ' + name); } root.createStubChild(name); stub = me.getStub(name); stub.setFormula(formulas[name]); } return formulas; }, applyLinks: function(links) { for (var link in links) { this.linkTo(link, links[link]); } }, applySchema: function(schema) { return Ext.data.schema.Schema.get(schema); }, applyRoot: function() { var root = new Ext.app.bind.RootStub(this), parent = this.getParent(); if (parent) { root.depth = parent.getRoot().depth - 1000; } return root; }, getFormulaFn: function(data) { var me = this, fn = me.formulaFn; if (!fn) { fn = me.formulaFn = function(name) { return me.$formulaData[name]; }; } me.$formulaData = data; return fn; } } }); Ext.define('Ext.app.domain.Controller', { extend: 'Ext.app.EventDomain', singleton: true, requires: [ 'Ext.app.Controller' ], type: 'controller', prefix: 'controller.', idMatchRe: /^\#/, constructor: function() { var me = this; me.callParent(); me.monitor(Ext.app.BaseController); }, match: function(target, selector) { var result = false, alias = target.alias; if (selector === '*') { result = true; } else if (selector === '#') { result = !!target.isApplication; } else if (this.idMatchRe.test(selector)) { result = target.getId() === selector.substring(1); } else if (alias) { result = Ext.Array.indexOf(alias, this.prefix + selector) > -1; } return result; } }); Ext.define('Ext.direct.Manager', { singleton: true, requires: [ 'Ext.util.MixedCollection' ], mixins: [ 'Ext.mixin.Observable' ], exceptions: { TRANSPORT: 'xhr', PARSE: 'parse', DATA: 'data', LOGIN: 'login', SERVER: 'exception' }, providerClasses: {}, remotingMethods: {}, config: { varName: 'Ext.app.REMOTING_API' }, apiNotFoundError: 'Ext Direct API was not found at {0}', constructor: function() { var me = this; me.mixins.observable.constructor.call(me); me.transactions = new Ext.util.MixedCollection(); me.providers = new Ext.util.MixedCollection(); }, addProvider: function(provider) { var me = this, args = arguments, relayers = me.relayers || (me.relayers = {}), i, len; if (args.length > 1) { for (i = 0 , len = args.length; i < len; ++i) { me.addProvider(args[i]); } return; } if (!provider.isProvider) { provider = Ext.create('direct.' + provider.type + 'provider', provider); } me.providers.add(provider); provider.on('data', me.onProviderData, me); if (provider.relayedEvents) { relayers[provider.id] = me.relayEvents(provider, provider.relayedEvents); } if (!provider.isConnected()) { provider.connect(); } return provider; }, loadProvider: function(config, callback, scope) { var me = this, classes = me.providerClasses, type, url, varName, provider, i, len; if (Ext.isArray(config)) { for (i = 0 , len = config.length; i < len; i++) { me.loadProvider(config[i], callback, scope); } return; } type = config.type; url = config.url; if (classes[type] && classes[type].checkConfig(config)) { provider = me.addProvider(config); me.fireEventArgs('providerload', [ url, provider ]); Ext.callback(callback, scope, [ url, provider ]); return; } varName = config.varName || me.getVarName(); delete config.varName; if (!url) { Ext.Error.raise("Need API discovery URL to load a Remoting provider!"); } delete config.url; Ext.Loader.loadScript({ url: url, scope: me, onLoad: function() { this.onApiLoadSuccess({ url: url, varName: varName, config: config, callback: callback, scope: scope }); }, onError: function() { this.onApiLoadFailure({ url: url, callback: callback, scope: scope }); } }); }, getProvider: function(id) { return id.isProvider ? id : this.providers.get(id); }, removeProvider: function(provider) { var me = this, providers = me.providers, relayers = me.relayers, id; provider = provider.isProvider ? provider : providers.get(provider); if (provider) { provider.un('data', me.onProviderData, me); id = provider.id; if (relayers[id]) { relayers[id].destroy(); delete relayers[id]; } providers.remove(provider); return provider; } return null; }, addTransaction: function(transaction) { this.transactions.add(transaction); return transaction; }, removeTransaction: function(transaction) { var me = this; transaction = me.getTransaction(transaction); me.transactions.remove(transaction); return transaction; }, getTransaction: function(transaction) { return typeof transaction === 'object' ? transaction : this.transactions.get(transaction); }, onProviderData: function(provider, event) { var me = this, i, len; if (Ext.isArray(event)) { for (i = 0 , len = event.length; i < len; ++i) { me.onProviderData(provider, event[i]); } return; } if (event.name && event.name !== 'event' && event.name !== 'exception') { me.fireEvent(event.name, event); } else if (event.status === false) { me.fireEvent('exception', event); } me.fireEvent('event', event, provider); }, parseMethod: function(fn) { var current = Ext.global, i = 0, resolved, parts, len; if (Ext.isFunction(fn)) { resolved = fn; } else if (Ext.isString(fn)) { resolved = this.remotingMethods[fn]; if (!resolved) { parts = fn.split('.'); len = parts.length; while (current && i < len) { current = current[parts[i]]; ++i; } resolved = Ext.isFunction(current) ? current : null; } } return resolved || null; }, privates: { addProviderClass: function(type, cls) { this.providerClasses[type] = cls; }, onApiLoadSuccess: function(options) { var me = this, url = options.url, varName = options.varName, api, provider, error; try { api = Ext.apply(options.config, eval(varName)); provider = me.addProvider(api); } catch (e) { error = e + ''; } if (error) { me.fireEventArgs('providerloaderror', [ url, error ]); Ext.callback(options.callback, options.scope, [ url, error ]); } else { me.fireEventArgs('providerload', [ url, provider ]); Ext.callback(options.callback, options.scope, [ url, provider ]); } }, onApiLoadFailure: function(options) { var url = options.url, error; error = Ext.String.format(this.apiNotFoundError, url); this.fireEventArgs('providerloaderror', [ url, error ]); Ext.callback(options.callback, options.scope, [ url, error ]); }, registerMethod: function(name, method) { this.remotingMethods[name] = method; }, clearAllMethods: function() { this.remotingMethods = {}; } } }, function() { Ext.Direct = Ext.direct.Manager; }); Ext.define('Ext.direct.Provider', { alias: 'direct.provider', mixins: [ 'Ext.util.Observable' ], requires: [ 'Ext.direct.Manager' ], isProvider: true, subscribers: 0, constructor: function(config) { var me = this; Ext.apply(me, config); Ext.applyIf(me, { id: Ext.id(null, 'provider-') }); me.mixins.observable.constructor.call(me, config); }, destroy: function() { var me = this; me.disconnect(true); me.mixins.observable.destroy.call(me); }, isConnected: function() { return this.subscribers > 0; }, connect: function() { var me = this; if (me.subscribers === 0) { me.doConnect(); me.fireEventArgs('connect', [ me ]); } me.subscribers++; }, doConnect: Ext.emptyFn, disconnect: function( force) { var me = this; if (me.subscribers > 0) { if (force) { me.subscribers = 0; } else { me.subscribers--; } if (me.subscribers === 0) { me.doDisconnect(); me.fireEventArgs('disconnect', [ me ]); } } }, doDisconnect: Ext.emptyFn, inheritableStatics: { checkConfig: Ext.returnFalse }, onClassExtended: function(cls, data, hooks) { if (data.type) { Ext.direct.Manager.addProviderClass(data.type, cls); } } }); Ext.define('Ext.app.domain.Direct', { extend: 'Ext.app.EventDomain', singleton: true, requires: [ 'Ext.direct.Provider' ], type: 'direct', idProperty: 'id', constructor: function() { var me = this; me.callParent(); me.monitor(Ext.direct.Provider); } }); Ext.define('Ext.data.PageMap', { extend: 'Ext.util.LruCache', config: { store: null, pageSize: 0, rootProperty: '' }, clear: function(initial) { var me = this; me.pageMapGeneration = (me.pageMapGeneration || 0) + 1; me.indexMap = {}; me.callParent(arguments); }, forEach: function(fn, scope) { var me = this, pageNumbers = Ext.Object.getKeys(me.map), pageCount = pageNumbers.length, pageSize = me.getPageSize(), i, j, pageNumber, page, len; for (i = 0; i < pageCount; i++) { pageNumbers[i] = +pageNumbers[i]; } Ext.Array.sort(pageNumbers, Ext.Array.numericSortFn); scope = scope || me; for (i = 0; i < pageCount; i++) { pageNumber = pageNumbers[i]; page = me.getPage(pageNumber); len = page.length; for (j = 0; j < len; j++) { if (fn.call(scope, page[j], (pageNumber - 1) * pageSize + j) === false) { return; } } } }, findBy: function(fn, scope) { var me = this, result = null; scope = scope || me; me.forEach(function(rec, index) { if (fn.call(scope, rec, index)) { result = rec; return false; } }); return result; }, findIndexBy: function(fn, scope) { var me = this, result = -1; scope = scope || me; me.forEach(function(rec, index) { if (fn.call(scope, rec)) { result = index; return false; } }); return result; }, find: function(property, value, start, startsWith, endsWith, ignoreCase) { if (Ext.isEmpty(value, false)) { return null; } var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase), root = this.getRootProperty(); return this.findBy(function(item) { return item && regex.test((root ? item[root] : item)[property]); }, null, start); }, findIndex: function(property, value, start, startsWith, endsWith, ignoreCase) { if (Ext.isEmpty(value, false)) { return null; } var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase), root = this.getRootProperty(); return this.findIndexBy(function(item) { return item && regex.test((root ? item[root] : item)[property]); }, null, start); }, getPageFromRecordIndex: function(index) { return Math.floor(index / this.getPageSize()) + 1; }, addAll: function(records) { if (this.getCount()) { Ext.Error.raise('Cannot addAll to a non-empty PageMap'); } this.addPage(1, records); }, addPage: function(pageNumber, records) { var me = this, pageSize = me.getPageSize(), lastPage = pageNumber + Math.floor((records.length - 1) / pageSize), startIdx, storeIndex = (pageNumber - 1) * pageSize, indexMap = me.indexMap, page, i, len; for (startIdx = 0; pageNumber <= lastPage; pageNumber++ , startIdx += pageSize) { page = Ext.Array.slice(records, startIdx, startIdx + pageSize); for (i = 0 , len = page.length; i < len; i++) { indexMap[page[i].internalId] = storeIndex++; } me.add(pageNumber, page); me.fireEvent('pageadd', me, pageNumber, page); } }, getCount: function() { var result = this.callParent(); if (result) { result = (result - 1) * this.getPageSize() + this.last.value.length; } return result; }, getByInternalId: function(internalId) { var index = this.indexMap[internalId]; if (index !== -1) { return this.getAt(index); } }, indexOf: function(record) { var result = -1; if (record) { result = this.indexMap[record.internalId]; if (result == null) { result = -1; } } return result; }, insert: function() { Ext.Error.raise('insert operation not suppported into buffered Store'); }, remove: function() { Ext.Error.raise('remove operation not suppported from buffered Store'); }, removeAt: function() { Ext.Error.raise('removeAt operation not suppported from buffered Store'); }, removeAtKey: function(page) { var me = this, thePage = me.getPage(page), len, i, result; if (thePage) { if (me.fireEvent('beforepageremove', me, page, thePage) !== false) { len = thePage.length; for (i = 0; i < len; i++) { delete me.indexMap[thePage[i].internalId]; } result = me.callParent(arguments); me.fireEvent('pageremove', me, page, thePage); thePage.length = 0; } } return result; }, getPage: function(pageNumber) { return this.get(pageNumber); }, hasRange: function(start, end) { var pageNumber = this.getPageFromRecordIndex(start), endPageNumber = this.getPageFromRecordIndex(end); for (; pageNumber <= endPageNumber; pageNumber++) { if (!this.hasPage(pageNumber)) { return false; } } return true; }, hasPage: function(pageNumber) { return !!this.get(pageNumber); }, peekPage: function(pageNumber) { return this.map[pageNumber]; }, getAt: function(index) { return this.getRange(index, index + 1)[0]; }, getRange: function(start, end) { end--; if (!this.hasRange(start, end)) { Ext.Error.raise('PageMap asked for range which it does not have'); } var me = this, pageSize = me.getPageSize(), startPageNumber = me.getPageFromRecordIndex(start), endPageNumber = me.getPageFromRecordIndex(end), dataStart = (startPageNumber - 1) * pageSize, dataEnd = (endPageNumber * pageSize) - 1, pageNumber = startPageNumber, result = [], sliceBegin, sliceEnd, doSlice; for (; pageNumber <= endPageNumber; pageNumber++) { if (pageNumber === startPageNumber) { sliceBegin = start - dataStart; doSlice = true; } else { sliceBegin = 0; doSlice = false; } if (pageNumber === endPageNumber) { sliceEnd = pageSize - (dataEnd - end); doSlice = true; } if (doSlice) { Ext.Array.push(result, Ext.Array.slice(me.getPage(pageNumber), sliceBegin, sliceEnd)); } else { Ext.Array.push(result, me.getPage(pageNumber)); } } return result; } }); Ext.define('Ext.data.BufferedStore', { extend: 'Ext.data.ProxyStore', alias: 'store.buffered', requires: [ 'Ext.data.PageMap', 'Ext.util.Filter', 'Ext.util.Sorter', 'Ext.util.Grouper' ], uses: [ 'Ext.util.SorterCollection', 'Ext.util.FilterCollection', 'Ext.util.GroupCollection' ], isBufferedStore: true, buffered: true, config: { data: 0, pageSize: 25, remoteSort: true, remoteFilter: true, sortOnLoad: false, purgePageCount: 5, trailingBufferZone: 25, leadingBufferZone: 200, defaultViewSize: 100, viewSize: 0, trackRemoved: false }, applyData: function(data) { var dataCollection = this.data || (this.data = this.createDataCollection()); if (data && data !== true) { Ext.Error.raise('Cannot load a buffered store with local data - the store is a map of remote data'); } return dataCollection; }, applyProxy: function(proxy) { proxy = this.callParent([ proxy ]); if (proxy && proxy.setEnablePaging) { proxy.setEnablePaging(true); } return proxy; }, createFiltersCollection: function() { return new Ext.util.FilterCollection(); }, createSortersCollection: function() { return new Ext.util.SorterCollection(); }, updateRemoteFilter: function(remoteFilter, oldRemoteFilter) { if (remoteFilter === false) { Ext.Error.raise('Buffered stores are always remotely filtered.'); } this.callParent([ remoteFilter, oldRemoteFilter ]); }, updateRemoteSort: function(remoteSort, oldRemoteSort) { if (remoteSort === false) { Ext.Error.raise('Buffered stores are always remotely sorted.'); } this.callParent([ remoteSort, oldRemoteSort ]); }, updateTrackRemoved: function(value) { if (value !== false) { Ext.Error.raise('Cannot use trackRemoved with a buffered store.'); } this.callParent(arguments); }, updateGroupField: function(field) { var me = this; if (me.isInitializing) { me.blockLoad(); } me.group(field); if (me.isInitializing) { me.unblockLoad(); } }, getGrouper: function() { return this.grouper; }, isGrouped: function() { return !!this.grouper; }, createDataCollection: function() { var me = this, result = new Ext.data.PageMap({ store: me, rootProperty: 'data', pageSize: me.getPageSize(), maxSize: me.getPurgePageCount(), listeners: { clear: me.onPageMapClear, scope: me } }); me.relayEvents(result, [ 'beforepageremove', 'pageadd', 'pageremove' ]); me.pageRequests = {}; return result; }, add: function() { Ext.Error.raise('add method may not be called on a buffered store - the store is a map of remote data'); }, insert: function() { Ext.Error.raise('insert method may not be called on a buffered store - the store is a map of remote data'); }, removeAll: function(silent) { var me = this, data = me.getData(); if (data) { if (silent) { me.suspendEvent('clear'); } data.clear(); if (silent) { me.resumeEvent('clear'); } } }, load: function(options) { var me = this; options = options || {}; me.getData().clear(); options.page = 1; options.start = 0; options.limit = me.getViewSize() || me.getDefaultViewSize(); options.loadCallback = options.callback; delete options.callback; return me.loadToPrefetch(options); }, reload: function(options) { var me = this, data = me.getData(), lastTotal = Number.MAX_VALUE, startIdx, endIdx, startPage, endPage, i, waitForReload, bufferZone, records; if (me.loading) { return; } if (!options) { options = {}; } data.clear(true); waitForReload = function() { if (me.rangeCached(startIdx, endIdx)) { me.loading = false; data.un('pageadd', waitForReload); records = data.getRange(startIdx, endIdx + 1); me.fireEvent('load', me, records, true); me.fireEvent('refresh', me); } }; bufferZone = Math.ceil((me.getLeadingBufferZone() + me.getTrailingBufferZone()) / 2); if (!me.lastRequestStart) { startIdx = options.start || 0; endIdx = startIdx + (options.count || me.getPageSize()) - 1; } else { startIdx = me.lastRequestStart; endIdx = me.lastRequestEnd; lastTotal = me.getTotalCount(); } delete me.totalCount; startIdx = Math.max(startIdx - bufferZone, 0); endIdx = Math.min(endIdx + bufferZone, lastTotal); startPage = me.getPageFromRecordIndex(startIdx); endPage = me.getPageFromRecordIndex(endIdx); if (me.fireEvent('beforeload', me, options) !== false) { me.loading = true; data.on('pageadd', waitForReload); for (i = startPage; i <= endPage; i++) { me.prefetchPage(i, options); } } }, filter: function() { if (!this.getRemoteFilter()) { Ext.Error.raise('Local filtering may not be used on a buffered store - the store is a map of remote data'); } this.getData().clear(); this.callParent(arguments); }, clearFilter: function() { this.getData().clear(); this.callParent(arguments); }, filterBy: function(fn, scope) { Ext.Error.raise('Local filtering may not be used on a buffered store - the store is a map of remote data'); }, loadData: function(data, append) { Ext.Error.raise('LoadData may not be used on a buffered store - the store is a map of remote data'); }, loadPage: function(page, options) { var me = this; options = options || {}; options.page = me.currentPage = page; options.start = (page - 1) * me.getPageSize(); options.limit = me.getViewSize() || me.getDefaultViewSize(); options.loadCallback = options.callback; delete options.callback; return me.loadToPrefetch(options); }, clearData: function(isLoad) { var me = this, data = me.getData(); if (data) { data.clear(); } }, getCount: function() { return this.totalCount || 0; }, getRange: function(start, end, options) { var me = this, maxIndex = me.totalCount - 1, lastRequestStart = me.lastRequestStart, result = [], data = me.getData(), pageAddHandler, requiredStart, requiredEnd, requiredStartPage, requiredEndPage; options = Ext.apply({ prefetchStart: start, prefetchEnd: end }, options); end = (end >= me.totalCount) ? maxIndex : end; requiredStart = start === 0 ? 0 : start - 1; requiredEnd = end === maxIndex ? end : end + 1; me.lastRequestStart = start; me.lastRequestEnd = end; if (me.rangeCached(requiredStart, requiredEnd)) { me.onRangeAvailable(options); result = data.getRange(start, end + 1); } else { me.fireEvent('cachemiss', me, start, end); requiredStartPage = me.getPageFromRecordIndex(requiredStart); requiredEndPage = me.getPageFromRecordIndex(requiredEnd); pageAddHandler = function(pageMap, page, records) { if (page >= requiredStartPage && page <= requiredEndPage && me.rangeCached(requiredStart, requiredEnd)) { me.fireEvent('cachefilled', me, start, end); data.un('pageadd', pageAddHandler); me.onRangeAvailable(options); } }; data.on('pageadd', pageAddHandler); me.prefetchRange(start, end); } me.primeCache(start, end, start < lastRequestStart ? -1 : 1); return result; }, getById: function(id) { var result = this.data.findBy(function(record) { return record.getId() === id; }); return result; }, getAt: function(index) { var data = this.getData(); if (data.hasRange(index, index)) { return data.getAt(index); } }, getByInternalId: function(internalId) { return this.data.getByInternalId(internalId); }, indexOf: function(record) { return this.getData().indexOf(record); }, indexOfId: function(id) { return this.indexOf(this.getById(id)); }, group: function(grouper, direction) { var me = this, oldGrouper; if (grouper && typeof grouper === 'string') { oldGrouper = me.grouper; if (!oldGrouper) { me.grouper = new Ext.util.Grouper({ property: grouper, direction: direction || 'ASC', root: 'data' }); } else if (direction === undefined) { oldGrouper.toggle(); } else { oldGrouper.setDirection(direction); } } else { me.grouper = grouper ? me.getSorters().decodeSorter(grouper, 'Ext.util.Grouper') : null; } if (me.isLoadBlocked()) { return; } me.getData().clear(); me.loadPage(1, { callback: function() { me.fireEvent('groupchange', me, me.getGrouper()); } }); }, getPageFromRecordIndex: function(index) { return Math.floor(index / this.getPageSize()) + 1; }, calculatePageCacheSize: function(rangeSizeRequested) { var me = this, purgePageCount = me.getPurgePageCount(); return purgePageCount ? Math.max(me.getData().getMaxSize() || 0, Math.ceil((rangeSizeRequested + me.getTrailingBufferZone() + me.getLeadingBufferZone()) / me.getPageSize()) * 2 + purgePageCount) : 0; }, loadToPrefetch: function(options) { var me = this, prefetchOptions = options, i, records, dataSetSize, startIdx = options.start, endIdx = options.start + options.limit - 1, rangeSizeRequested = (me.getViewSize() || options.limit), loadEndIdx = Math.min(endIdx, options.start + rangeSizeRequested - 1), startPage = me.getPageFromRecordIndex(Math.max(startIdx - me.getTrailingBufferZone(), 0)), endPage = me.getPageFromRecordIndex(endIdx + me.getLeadingBufferZone()), data = me.getData(), callbackFn = function() { records = records || []; if (options.loadCallback) { options.loadCallback.call(options.scope || me, records, operation, true); } if (options.callback) { options.callback.call(options.scope || me, records, startIdx || 0, endIdx || 0, options); } }, fireEventsFn = function() { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); me.fireEvent('load', me, records, true); }, waitForRequestedRange = function() { if (me.rangeCached(startIdx, loadEndIdx)) { me.loading = false; records = data.getRange(startIdx, loadEndIdx + 1); data.un('pageadd', waitForRequestedRange); if (me.hasListeners.guaranteedrange) { me.guaranteeRange(startIdx, loadEndIdx, options.callback, options.scope); } callbackFn(); fireEventsFn(); } }, operation; if (isNaN(me.pageSize) || !me.pageSize) { Ext.Error.raise('Buffered store configured without a pageSize', me); } data.setMaxSize(me.calculatePageCacheSize(rangeSizeRequested)); if (me.fireEvent('beforeload', me, options) !== false) { delete me.totalCount; me.loading = true; if (options.callback) { prefetchOptions = Ext.apply({}, options); delete prefetchOptions.callback; } me.on('prefetch', function(store, records, successful, op) { operation = op; if (successful) { if ((dataSetSize = me.getTotalCount())) { data.on('pageadd', waitForRequestedRange); loadEndIdx = Math.min(loadEndIdx, dataSetSize - 1); endPage = me.getPageFromRecordIndex(Math.min(loadEndIdx + me.getLeadingBufferZone(), dataSetSize - 1)); for (i = startPage + 1; i <= endPage; ++i) { me.prefetchPage(i, prefetchOptions); } } else { callbackFn(); fireEventsFn(); } } else { callbackFn(); me.fireEvent('load', me, records, false); } }, null, { single: true }); me.prefetchPage(startPage, prefetchOptions); } }, prefetch: function(options) { var me = this, pageSize = me.getPageSize(), data = me.getData(), operation; if (pageSize) { if (me.lastPageSize && pageSize != me.lastPageSize) { Ext.Error.raise("pageSize cannot be dynamically altered"); } if (!data.getPageSize()) { data.setPageSize(pageSize); } } else { me.pageSize = data.setPageSize(pageSize = options.limit); } me.lastPageSize = pageSize; if (!options.page) { options.page = me.getPageFromRecordIndex(options.start); options.start = (options.page - 1) * pageSize; options.limit = Math.ceil(options.limit / pageSize) * pageSize; } if (!me.pageRequests[options.page]) { options = Ext.apply({ action: 'read', filters: me.getFilters().items, sorters: me.getSorters().items, grouper: me.getGrouper(), internalCallback: me.onProxyPrefetch, internalScope: me }, options); operation = me.createOperation('read', options); operation.pageMapGeneration = data.pageMapGeneration; if (me.fireEvent('beforeprefetch', me, operation) !== false) { me.pageRequests[options.page] = operation.execute(); if (me.getProxy().isSynchronous) { delete me.pageRequests[options.page]; } } } return me; }, onPageMapClear: function() { var me = this, loadingFlag = me.wasLoading, reqs = me.pageRequests, data = me.getData(), req, page; data.clearListeners(); data.on('clear', me.onPageMapClear, me); me.relayEvents(data, [ 'beforepageremove', 'pageadd', 'pageremove' ]); me.loading = true; me.totalCount = 0; for (page in reqs) { if (reqs.hasOwnProperty(page)) { req = reqs[page]; delete reqs[page]; delete req.callback; } } me.fireEvent('clear', me); me.loading = loadingFlag; }, prefetchPage: function(page, options) { var me = this, pageSize = me.getPageSize(), start = (page - 1) * pageSize, total = me.totalCount; if (total !== undefined && me.data.getCount() === total) { return; } me.prefetch(Ext.applyIf({ page: page, start: start, limit: pageSize }, options)); }, onProxyPrefetch: function(operation) { var me = this, resultSet = operation.getResultSet(), records = operation.getRecords(), successful = operation.wasSuccessful(), page = operation.getPage(), oldTotal = me.totalCount; if (operation.pageMapGeneration === me.getData().pageMapGeneration) { if (resultSet) { me.totalCount = resultSet.getTotal(); if (me.totalCount !== oldTotal) { me.fireEvent('totalcountchange', me.totalCount); } } if (page !== undefined) { delete me.pageRequests[page]; } me.loading = false; me.fireEvent('prefetch', me, records, successful, operation); if (successful) { me.cachePage(records, operation.getPage()); } Ext.callback(operation.getCallback(), operation.getScope() || me, [ records, operation, successful ]); } }, cachePage: function(records, page) { var me = this, len = records.length, i; if (!Ext.isDefined(me.totalCount)) { me.totalCount = records.length; me.fireEvent('totalcountchange', me.totalCount); } for (i = 0; i < len; i++) { records[i].join(me); } me.getData().addPage(page, records); }, rangeCached: function(start, end) { return this.getData().hasRange(start, end); }, pageCached: function(page) { return this.getData().hasPage(page); }, pagePending: function(page) { return !!this.pageRequests[page]; }, rangeSatisfied: function(start, end) { return this.rangeCached(start, end); }, onRangeAvailable: function(options) { var me = this, totalCount = me.getTotalCount(), start = options.prefetchStart, end = (options.prefetchEnd > totalCount - 1) ? totalCount - 1 : options.prefetchEnd, range; end = Math.max(0, end); if (start > end) { Ext.log({ level: 'warn', msg: 'Start (' + start + ') was greater than end (' + end + ') for the range of records requested (' + start + '-' + options.prefetchEnd + ')' + (this.storeId ? ' from store "' + this.storeId + '"' : '') }); } range = me.getData().getRange(start, end + 1); if (options.fireEvent !== false) { me.fireEvent('guaranteedrange', range, start, end, options); } if (options.callback) { options.callback.call(options.scope || me, range, start, end, options); } }, guaranteeRange: function(start, end, callback, scope, options) { options = Ext.apply({ callback: callback, scope: scope }, options); this.getRange(start, end + 1, options); }, prefetchRange: function(start, end) { var me = this, startPage, endPage, page, data = me.getData(); if (!me.rangeCached(start, end)) { startPage = me.getPageFromRecordIndex(start); endPage = me.getPageFromRecordIndex(end); data.setMaxSize(me.calculatePageCacheSize(end - start + 1)); for (page = startPage; page <= endPage; page++) { if (!me.pageCached(page)) { me.prefetchPage(page); } } } }, primeCache: function(start, end, direction) { var me = this, leadingBufferZone = me.getLeadingBufferZone(), trailingBufferZone = me.getTrailingBufferZone(), pageSize = me.getPageSize(), totalCount = me.totalCount; if (direction === -1) { start = Math.max(start - leadingBufferZone, 0); end = Math.min(end + trailingBufferZone, totalCount - 1); } else if (direction === 1) { start = Math.max(Math.min(start - trailingBufferZone, totalCount - pageSize), 0); end = Math.min(end + leadingBufferZone, totalCount - 1); } else { start = Math.min(Math.max(Math.floor(start - ((leadingBufferZone + trailingBufferZone) / 2)), 0), totalCount - me.pageSize); end = Math.min(Math.max(Math.ceil(end + ((leadingBufferZone + trailingBufferZone) / 2)), 0), totalCount - 1); } me.prefetchRange(start, end); }, sort: function(field, direction, mode) { if (arguments.length === 0) { this.clearAndLoad(); } else { this.getSorters().addSort(field, direction, mode); } }, onSorterEndUpdate: function() { var me = this, sorters = me.getSorters().getRange(); if (sorters.length) { me.clearAndLoad({ callback: function() { me.fireEvent('sort', me, sorters); } }); } else { me.fireEvent('sort', me, sorters); } }, clearAndLoad: function(options) { if (this.isLoadBlocked()) { return; } this.getData().clear(); this.loadPage(1, options); }, privates: { isLast: function(record) { return this.indexOf(record) === this.getTotalCount() - 1; }, isMoving: function() { return false; } } }); Ext.define('Ext.data.proxy.Direct', { extend: 'Ext.data.proxy.Server', alternateClassName: 'Ext.data.DirectProxy', alias: 'proxy.direct', requires: [ 'Ext.direct.Manager' ], config: { paramOrder: undefined, paramsAsHash: true, directFn: undefined, api: undefined, metadata: undefined }, paramOrderRe: /[\s,|]/, applyParamOrder: function(paramOrder) { if (Ext.isString(paramOrder)) { paramOrder = paramOrder.split(this.paramOrderRe); } return paramOrder; }, updateApi: function() { this.methodsResolved = false; }, updateDirectFn: function() { this.methodsResolved = false; }, resolveMethods: function() { var me = this, fn = me.getDirectFn(), api = me.getApi(), Manager = Ext.direct.Manager, method; if (fn) { me.setDirectFn(method = Manager.parseMethod(fn)); if (!Ext.isFunction(method)) { Ext.Error.raise('Cannot resolve directFn ' + fn); } } if (api) { for (fn in api) { if (api.hasOwnProperty(fn)) { method = api[fn]; api[fn] = Manager.parseMethod(method); if (!Ext.isFunction(api[fn])) { Ext.Error.raise('Cannot resolve Direct api ' + fn + ' method ' + method); } } } } me.methodsResolved = true; }, doRequest: function(operation) { var me = this, writer, request, action, params, args, api, fn, callback; if (!me.methodsResolved) { me.resolveMethods(); } request = me.buildRequest(operation); action = request.getAction(); api = me.getApi(); if (api) { fn = api[action]; } fn = fn || me.getDirectFn(); if (!fn) { Ext.Error.raise('No Ext.Direct function specified for this proxy'); } writer = me.getWriter(); if (writer && operation.allowWrite()) { request = writer.write(request); } if (action === 'read') { params = request.getParams(); } else { params = request.getJsonData(); } args = fn.directCfg.method.getArgs({ params: params, paramOrder: me.getParamOrder(), paramsAsHash: me.getParamsAsHash(), metadata: me.getMetadata(), callback: me.createRequestCallback(request, operation), scope: me }); request.setConfig({ args: args, directFn: fn }); fn.apply(window, args); return request; }, applyEncoding: Ext.identityFn, createRequestCallback: function(request, operation) { var me = this; return function(data, event) { me.processResponse(event.status, operation, request, event); }; }, extractResponseData: function(response) { return Ext.isDefined(response.result) ? response.result : response.data; }, setException: function(operation, response) { operation.setException(response.message); }, buildUrl: function() { return ''; } }); Ext.define('Ext.data.DirectStore', { extend: 'Ext.data.Store', 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' } }; Ext.copyTo(proxy, config, 'paramOrder,paramsAsHash,directFn,api,simpleSortMode,extraParams'); Ext.copyTo(proxy.reader, config, 'totalProperty,root,rootProperty,idProperty'); config.proxy = proxy; } this.callParent([ config ]); } }); Ext.define('Ext.data.JsonP', { singleton: true, requestCount: 0, requests: {}, timeout: 30000, disableCaching: true, disableCachingParam: '_dc', callbackKey: 'callback', request: function(options) { options = Ext.apply({}, options); if (!options.url) { Ext.Error.raise('A url must be specified for a JSONP request.'); } var me = this, disableCaching = Ext.isDefined(options.disableCaching) ? options.disableCaching : me.disableCaching, cacheParam = options.disableCachingParam || me.disableCachingParam, id = ++me.requestCount, callbackName = options.callbackName || 'callback' + id, callbackKey = options.callbackKey || me.callbackKey, timeout = Ext.isDefined(options.timeout) ? options.timeout : me.timeout, params = Ext.apply({}, options.params), url = options.url, name = Ext.name, request, script; if (disableCaching && !params[cacheParam]) { params[cacheParam] = Ext.Date.now(); } options.params = params; params[callbackKey] = name + '.data.JsonP.' + callbackName; script = me.createScript(url, params, options); me.requests[id] = request = { url: url, params: params, script: script, id: id, scope: options.scope, success: options.success, failure: options.failure, callback: options.callback, callbackKey: callbackKey, callbackName: callbackName }; if (timeout > 0) { request.timeout = Ext.defer(me.handleTimeout, timeout, me, [ request ]); } me.setupErrorHandling(request); me[callbackName] = Ext.bind(me.handleResponse, me, [ request ], true); me.loadScript(request); return request; }, abort: function(request) { var me = this, requests = me.requests, key; if (request) { if (!request.id) { request = requests[request]; } me.handleAbort(request); } else { for (key in requests) { if (requests.hasOwnProperty(key)) { me.abort(requests[key]); } } } }, setupErrorHandling: function(request) { request.script.onerror = Ext.bind(this.handleError, this, [ request ]); }, handleAbort: function(request) { request.errorType = 'abort'; this.handleResponse(null, request); }, handleError: function(request) { request.errorType = 'error'; this.handleResponse(null, request); }, cleanupErrorHandling: function(request) { request.script.onerror = null; }, handleTimeout: function(request) { request.errorType = 'timeout'; this.handleResponse(null, request); }, handleResponse: function(result, request) { var success = true, globalEvents = Ext.GlobalEvents; if (request.timeout) { clearTimeout(request.timeout); } delete this[request.callbackName]; delete this.requests[request.id]; this.cleanupErrorHandling(request); Ext.fly(request.script).destroy(); 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 ]); if (globalEvents.hasListeners.idle) { globalEvents.fireEvent('idle'); } }, createScript: function(url, params, options) { 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; }, loadScript: function(request) { Ext.getHead().appendChild(request.script); } }); Ext.define('Ext.data.proxy.JsonP', { extend: 'Ext.data.proxy.Server', alternateClassName: 'Ext.data.ScriptTagProxy', alias: [ 'proxy.jsonp', 'proxy.scripttag' ], requires: [ 'Ext.data.JsonP' ], config: { callbackKey: 'callback', recordParam: 'records', autoAppendParams: true }, doRequest: function(operation) { var me = this, request = me.buildRequest(operation), params = request.getParams(); request.setConfig({ callbackKey: me.callbackKey, timeout: me.timeout, scope: me, disableCaching: false, callback: me.createRequestCallback(request, operation) }); if (me.getAutoAppendParams()) { request.setParams({}); } request.setRawRequest(Ext.data.JsonP.request(request.getCurrentConfig())); request.setParams(params); me.lastRequest = request; return request; }, createRequestCallback: function(request, operation) { var me = this; return function(success, response, errorType) { if (request === me.lastRequest) { me.lastRequest = null; } me.processResponse(success, operation, request, response); }; }, setException: function(operation, response) { operation.setException(operation.getRequest().getRawRequest().errorType); }, buildUrl: function(request) { var me = this, url = me.callParent(arguments), records = request.getRecords(), writer = me.getWriter(), params, filters, filter, i, v; if (writer && request.getOperation().allowWrite()) { request = writer.write(request); } params = request.getParams(); filters = params.filters; delete params.filters; if (filters && filters.length) { for (i = 0; i < filters.length; i++) { filter = filters[i]; v = filter.getValue(); if (v) { params[filter.getProperty()] = v; } } } if (Ext.isArray(records) && records.length > 0 && (!writer || !writer.getEncode())) { params[me.getRecordParam()] = me.encodeRecords(records); } if (me.getAutoAppendParams()) { url = Ext.urlAppend(url, Ext.Object.toQueryString(params)); } return url; }, abort: function(request) { request = request || this.lastRequest; if (request) { Ext.data.JsonP.abort(request.getRawRequest()); } }, encodeRecords: function(records) { var encoded = [], i = 0, len = records.length; for (; i < len; i++) { encoded.push(Ext.encode(records[i].getData())); } return encoded; } }); Ext.define('Ext.data.JsonPStore', { extend: 'Ext.data.Store', alias: 'store.jsonp', requires: [ 'Ext.data.proxy.JsonP', 'Ext.data.reader.Json' ], constructor: function(config) { config = Ext.apply({ proxy: { type: 'jsonp', reader: 'json' } }, config); this.callParent([ config ]); } }); Ext.define('Ext.data.JsonStore', { extend: 'Ext.data.Store', alias: 'store.json', requires: [ 'Ext.data.proxy.Ajax', 'Ext.data.reader.Json', 'Ext.data.writer.Json' ], constructor: function(config) { config = Ext.apply({ proxy: { type: 'ajax', reader: 'json', writer: 'json' } }, config); this.callParent([ config ]); } }); Ext.define('Ext.data.ModelManager', { alternateClassName: 'Ext.ModelMgr', requires: [ 'Ext.data.schema.Schema' ], singleton: true, deprecated: { 5: { methods: { clear: null, create: function(data, name, id) { var T = name; if (!T.isEntity) { T = this.getModel(name || data.name); } return T.createWithId(id, data); }, each: function(fn, scope) { Ext.data.Model.schema.eachEntity(fn, scope); }, get: function(name) { return this.getModel(name); }, getCount: function() { return Ext.data.Model.schema.entityCount; }, getModel: function(id) { return Ext.data.schema.Schema.lookupEntity(id); }, isRegistered: function(name) { return !!this.getModel(name); } } } } }); Ext.define('Ext.data.NodeInterface', { requires: [ 'Ext.data.field.Boolean', 'Ext.data.field.Integer', 'Ext.data.field.String', 'Ext.data.writer.Json', 'Ext.mixin.Observable' ], statics: { decorate: function(modelClass) { var model = Ext.data.schema.Schema.lookupEntity(modelClass), proto = model.prototype, idName, idField, idType; if (!model.prototype.isObservable) { model.mixin(Ext.mixin.Observable.prototype.mixinId, Ext.mixin.Observable); } if (proto.isNode) { return; } idName = proto.idProperty; idField = model.getField(idName); idType = idField.type; model.override(this.getPrototypeBody()); model.addFields([ { name: 'parentId', type: idType, defaultValue: null, allowNull: idField.allowNull }, { name: 'index', type: 'int', defaultValue: -1, persist: false, convert: null }, { name: 'depth', type: 'int', defaultValue: 0, persist: false, convert: null }, { name: 'expanded', type: 'bool', defaultValue: false, persist: false, convert: null }, { name: 'expandable', type: 'bool', defaultValue: true, persist: false, convert: null }, { name: 'checked', type: 'auto', defaultValue: null, persist: false, convert: null }, { name: 'leaf', type: 'bool', defaultValue: false }, { name: 'cls', type: 'string', defaultValue: '', persist: false, convert: null }, { name: 'iconCls', type: 'string', defaultValue: '', persist: false, convert: null }, { name: 'icon', type: 'string', defaultValue: '', persist: false, convert: null }, { name: 'root', type: 'boolean', defaultValue: false, persist: false, convert: null }, { name: 'isLast', type: 'boolean', defaultValue: false, persist: false, convert: null }, { name: 'isFirst', type: 'boolean', defaultValue: false, persist: false, convert: null }, { name: 'allowDrop', type: 'boolean', defaultValue: true, persist: false, convert: null }, { name: 'allowDrag', type: 'boolean', defaultValue: true, persist: false, convert: null }, { name: 'loaded', type: 'boolean', defaultValue: false, persist: false, convert: null }, { name: 'loading', type: 'boolean', defaultValue: false, persist: false, convert: null }, { name: 'href', type: 'string', defaultValue: '', persist: false, convert: null }, { name: 'hrefTarget', type: 'string', defaultValue: '', persist: false, convert: null }, { name: 'qtip', type: 'string', defaultValue: '', persist: false, convert: null }, { name: 'qtitle', type: 'string', defaultValue: '', persist: false, convert: null }, { name: 'qshowDelay', type: 'int', defaultValue: 0, persist: false, convert: null }, { name: 'children', type: 'auto', defaultValue: null, persist: false, convert: null }, { name: 'visible', type: 'boolean', defaultValue: true, persist: false }, { name: 'text', type: 'string', persist: false } ]); }, getPrototypeBody: function() { var bubbledEvents = { idchanged: true, append: true, remove: true, move: true, insert: true, beforeappend: true, beforeremove: true, beforemove: true, beforeinsert: true, expand: true, collapse: true, beforeexpand: true, beforecollapse: true, sort: true }, silently = { silent: true }; return { isNode: true, firstChild: null, lastChild: null, parentNode: null, previousSibling: null, nextSibling: null, constructor: function() { var me = this; me.mixins.observable.constructor.call(me); me.callParent(arguments); me.childNodes = []; return me; }, createNode: function(node) { var me = this, childType = me.childType, store, storeReader, nodeProxy, nodeReader, reader, typeProperty, T = me.self; if (!node.isModel) { if (childType) { T = me.schema.getEntity(childType); } else { store = me.getTreeStore(); storeReader = store && store.getProxy().getReader(); nodeProxy = me.getProxy(); nodeReader = nodeProxy ? nodeProxy.getReader() : null; reader = !storeReader || (nodeReader && nodeReader.initialConfig.typeProperty) ? nodeReader : storeReader; if (reader) { typeProperty = reader.getTypeProperty(); if (typeProperty) { T = reader.getChildType(me.schema, node, typeProperty); } } } node = new T(node); } if (!node.childNodes) { node.firstChild = node.lastChild = node.parentNode = node.previousSibling = node.nextSibling = null; node.childNodes = []; } return node; }, isLeaf: function() { return this.get('leaf') === true; }, setFirstChild: function(node) { this.firstChild = node; }, setLastChild: function(node) { this.lastChild = node; }, updateInfo: function(commit, info) { var me = this, dataObject = me.data, oldDepth = dataObject.depth, childInfo = {}, children = me.childNodes, childCount = children.length, phantom = me.phantom, fields = me.fields, modified = me.modified || (me.modified = {}), propName, newValue, field, currentValue, key, newParentId = info.parentId, settingIndexInNewParent, persistentField, i; if (!info) { Ext.Error.raise('NodeInterface expects update info to be passed'); } for (propName in info) { field = fields[me.fieldOrdinals[propName]]; newValue = info[propName]; persistentField = field && field.persist; currentValue = dataObject[propName]; settingIndexInNewParent = persistentField && (propName === 'index') && (currentValue !== -1) && (newParentId && newParentId !== modified.parentId); if (!settingIndexInNewParent && me.isEqual(currentValue, newValue)) { continue; } dataObject[propName] = newValue; if (persistentField) { if (!settingIndexInNewParent && modified.hasOwnProperty(propName)) { if (me.isEqual(modified[propName], newValue)) { delete modified[propName]; me.dirty = false; for (key in modified) { if (modified.hasOwnProperty(key)) { me.dirty = true; break; } } } } else { me.dirty = true; modified[propName] = currentValue; } } } if (commit) { me.commit(); me.phantom = phantom; } if (me.data.depth !== oldDepth) { childInfo = { depth: me.data.depth + 1 }; for (i = 0; i < childCount; i++) { children[i].updateInfo(commit, childInfo); } } }, isLast: function() { return this.get('isLast'); }, isFirst: function() { return this.get('isFirst'); }, hasChildNodes: function() { return !this.isLeaf() && this.childNodes.length > 0; }, isExpandable: function() { var me = this; if (me.get('expandable')) { return !(me.isLeaf() || (me.isLoaded() && !me.phantom && !me.hasChildNodes())); } return false; }, triggerUIUpdate: function() { this.callJoined('afterEdit', []); }, appendChild: function(node, suppressEvents, commit) { var me = this, i, ln, index, oldParent, previousSibling, childInfo = { isLast: true, parentId: me.getId(), depth: (me.data.depth || 0) + 1 }, result, treeStore = me.getTreeStore(), bulkUpdate = treeStore && treeStore.bulkUpdate; Ext.suspendLayouts(); if (Ext.isArray(node)) { ln = node.length; result = new Array(ln); me.callTreeStore('beginFill'); for (i = 0; i < ln; i++) { result[i] = me.appendChild(node[i], suppressEvents, commit); } me.callTreeStore('endFill', [ result ]); } else { node = me.createNode(node); if (suppressEvents !== true && me.fireEventArgs('beforeappend', [ me, node ]) === false) { Ext.resumeLayouts(true); return false; } index = me.childNodes.length; oldParent = node.parentNode; if (oldParent) { if (suppressEvents !== true && node.fireEventArgs('beforemove', [ node, oldParent, me, index ]) === false) { Ext.resumeLayouts(true); return false; } if (oldParent.removeChild(node, false, suppressEvents, oldParent.getTreeStore() === treeStore) === false) { Ext.resumeLayouts(true); return false; } } treeStore && treeStore.beginUpdate(); index = me.childNodes.length; if (index === 0) { me.setFirstChild(node); } me.childNodes[index] = node; node.parentNode = me; node.nextSibling = null; me.setLastChild(node); previousSibling = me.childNodes[index - 1]; if (previousSibling) { node.previousSibling = previousSibling; previousSibling.nextSibling = node; previousSibling.updateInfo(commit, { isLast: false }); if (!bulkUpdate) { previousSibling.triggerUIUpdate(); } } else { node.previousSibling = null; } childInfo.isFirst = index === 0; childInfo.index = index; node.updateInfo(commit, childInfo); if (me.isLeaf()) { me.set('leaf', false); } if (!me.isLoaded()) { if (bulkUpdate) { me.data.loaded = true; } else { me.set('loaded', true); } } else if (me.childNodes.length === 1 && !bulkUpdate) { me.triggerUIUpdate(); } if (index && me.childNodes[index - 1].isExpanded() && !bulkUpdate) { me.childNodes[index - 1].cascadeBy(me.triggerUIUpdate); } if (treeStore) { treeStore.registerNode(me, !bulkUpdate); if (bulkUpdate) { treeStore.registerNode(node); } } if (suppressEvents !== true) { me.fireEventArgs('append', [ me, node, index ]); if (oldParent) { node.fireEventArgs('move', [ node, oldParent, me, index ]); } } me.callTreeStore('onNodeAppend', [ node, index ]); result = node; if (treeStore) { treeStore.endUpdate(); } } Ext.resumeLayouts(true); return result; }, getOwnerTree: function() { var store = this.getTreeStore(); if (store) { return store.ownerTree; } }, getTreeStore: function() { var root = this; while (root && !root.treeStore) { root = root.parentNode; } return root && root.treeStore; }, removeChild: function(node, erase, suppressEvents, isMove) { var me = this, index = me.indexOf(node), i, childCount, previousSibling, treeStore = me.getTreeStore(), bulkUpdate = treeStore && treeStore.bulkUpdate, removeContext; if (index === -1 || (suppressEvents !== true && me.fireEventArgs('beforeremove', [ me, node, !!isMove ]) === false)) { return false; } Ext.suspendLayouts(); treeStore && treeStore.beginUpdate(); Ext.Array.erase(me.childNodes, index, 1); if (me.firstChild === node) { me.setFirstChild(node.nextSibling); } if (me.lastChild === node) { me.setLastChild(node.previousSibling); } previousSibling = node.previousSibling; if (previousSibling) { node.previousSibling.nextSibling = node.nextSibling; } if (node.nextSibling) { node.nextSibling.previousSibling = node.previousSibling; if (index === 0) { node.nextSibling.updateInfo(false, { isFirst: true }); } for (i = index , childCount = me.childNodes.length; i < childCount; i++) { me.childNodes[i].updateInfo(false, { index: i }); } } else if (previousSibling) { previousSibling.updateInfo(false, { isLast: true }); if (!bulkUpdate) { if (previousSibling.isExpanded()) { previousSibling.cascadeBy(me.triggerUIUpdate); } else { previousSibling.triggerUIUpdate(); } } } if (!me.childNodes.length && !bulkUpdate) { me.triggerUIUpdate(); } Ext.resumeLayouts(true); if (suppressEvents !== true) { removeContext = { parentNode: node.parentNode, previousSibling: node.previousSibling, nextSibling: node.nextSibling }; me.callTreeStore('beforeNodeRemove', [ [ node ], !!isMove ]); node.previousSibling = node.nextSibling = node.parentNode = null; me.fireEventArgs('remove', [ me, node, !!isMove, removeContext ]); me.callTreeStore('onNodeRemove', [ [ node ], !!isMove ]); } if (erase) { node.erase(true); } else { node.clear(); } if (!isMove) { node.set({ parentId: null, lastParentId: me.getId() }, silently); } if (treeStore) { treeStore.endUpdate(); } return node; }, copy: function(newId, deep) { var me = this, result = me.callParent([ newId ]), len = me.childNodes ? me.childNodes.length : 0, i; if (deep) { for (i = 0; i < len; i++) { result.appendChild(me.childNodes[i].copy(undefined, true)); } } return result; }, clear: function(erase) { var me = this; me.parentNode = me.previousSibling = me.nextSibling = null; if (erase) { me.firstChild = me.lastChild = me.childNodes = null; } }, drop: function() { var me = this, childNodes = me.childNodes, parentNode = me.parentNode, len = childNodes ? childNodes.length : 0, i, node, treeStore; me.callParent(); if (parentNode) { treeStore = me.getTreeStore(); parentNode.removeChild(me); } else if (me.get('root')) { treeStore = me.getTreeStore(); treeStore.setRoot(null); } treeStore && treeStore.beginUpdate(); for (i = 0; i < len; i++) { node = childNodes[i]; node.clear(); node.drop(); } treeStore && treeStore.endUpdate(); }, erase: function(options) { var me = this, childNodes = me.childNodes, len = childNodes && childNodes.length, i, node; me.remove(); me.clear(true); me.callParent([ options ]); for (i = 0; i < len; i++) { node = childNodes[i]; node.parentNode = null; node.erase(options); } }, insertBefore: function(node, refNode, suppressEvents) { var me = this, index = me.indexOf(refNode), oldParent = node.parentNode, refIndex = index, childCount, previousSibling, i, treeStore = me.getTreeStore(), bulkUpdate = treeStore && treeStore.bulkUpdate; if (!refNode) { return me.appendChild(node); } if (node === refNode) { return false; } node = me.createNode(node); if (suppressEvents !== true && me.fireEventArgs('beforeinsert', [ me, node, refNode ]) === false) { return false; } if (oldParent === me && me.indexOf(node) < index) { refIndex--; } if (oldParent) { if (suppressEvents !== true && node.fireEventArgs('beforemove', [ node, oldParent, me, index, refNode ]) === false) { return false; } if (oldParent.removeChild(node, false, suppressEvents, oldParent.getTreeStore() === treeStore) === false) { return false; } } treeStore && treeStore.beginUpdate(); if (refIndex === 0) { me.setFirstChild(node); } Ext.Array.splice(me.childNodes, refIndex, 0, node); node.parentNode = me; node.nextSibling = refNode; refNode.previousSibling = node; previousSibling = me.childNodes[refIndex - 1]; if (previousSibling) { node.previousSibling = previousSibling; previousSibling.nextSibling = node; } else { node.previousSibling = null; } node.updateInfo(false, { parentId: me.getId(), index: refIndex, isFirst: refIndex === 0, isLast: false, depth: (me.data.depth || 0) + 1 }); for (i = refIndex + 1 , childCount = me.childNodes.length; i < childCount; i++) { me.childNodes[i].updateInfo(false, { index: i }); } if (!me.isLoaded()) { if (bulkUpdate) { me.data.loaded = true; } else { me.set('loaded', true); } } else if (me.childNodes.length === 1 && !bulkUpdate) { me.triggerUIUpdate(); } if (treeStore) { treeStore.registerNode(me, !bulkUpdate); } if (suppressEvents !== true) { me.fireEventArgs('insert', [ me, node, refNode ]); if (oldParent) { node.fireEventArgs('move', [ node, oldParent, me, refIndex, refNode ]); } } me.callTreeStore('onNodeInsert', [ node, refIndex ]); if (treeStore) { treeStore.endUpdate(); } return node; }, insertChild: function(index, node) { var sibling = this.childNodes[index]; if (sibling) { return this.insertBefore(node, sibling); } else { return this.appendChild(node); } }, isLastVisible: function() { var me = this, result = me.data.isLast, next = me.nextSibling; if (!result && me.getTreeStore().isFiltered()) { while (next) { if (next.data.visible) { return false; } next = next.nextSibling; } return true; } return result; }, remove: function(erase, suppressEvents) { var me = this, parentNode = me.parentNode; if (parentNode) { parentNode.removeChild(me, erase, suppressEvents); } else if (erase) { me.erase(true); } return me; }, removeAll: function(erase, suppressEvents, fromParent) { var me = this, childNodes = me.childNodes, len = childNodes.length, node, treeStore, i; if (!len) { return; } if (!fromParent) { treeStore = me.getTreeStore(); if (treeStore) { treeStore.beginUpdate(); treeStore.suspendEvent('remove'); me.callTreeStore('beforeNodeRemove', [ childNodes, false ]); } } for (i = 0; i < len; ++i) { node = childNodes[i]; node.previousSibling = node.nextSibling = node.parentNode = null; me.fireEventArgs('remove', [ me, node, false ]); if (erase) { node.erase(true); } else { node.removeAll(false, suppressEvents, true); } } if (!fromParent && treeStore) { treeStore.resumeEvent('remove'); me.callTreeStore('onNodeRemove', [ childNodes, false ]); treeStore.endUpdate(); } me.firstChild = me.lastChild = null; childNodes.length = 0; if (!fromParent) { me.triggerUIUpdate(); } return me; }, getChildAt: function(index) { return this.childNodes[index]; }, replaceChild: function(newChild, oldChild, suppressEvents) { var s = oldChild ? oldChild.nextSibling : null; this.removeChild(oldChild, false, suppressEvents); this.insertBefore(newChild, s, suppressEvents); return oldChild; }, indexOf: function(child) { return Ext.Array.indexOf(this.childNodes, child); }, indexOfId: function(id) { var childNodes = this.childNodes, len = childNodes.length, i = 0; for (; i < len; ++i) { if (childNodes[i].getId() === id) { return i; } } return -1; }, getPath: function(field, separator) { field = field || this.idProperty; separator = separator || '/'; var path = [ this.get(field) ], parent = this.parentNode; while (parent) { path.unshift(parent.get(field)); parent = parent.parentNode; } return separator + path.join(separator); }, getDepth: function() { return this.get('depth'); }, bubble: function(fn, scope, args) { var p = this; while (p) { if (fn.apply(scope || p, args || [ p ]) === false) { break; } p = p.parentNode; } }, 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); }, cascadeBy: function(before, scope, args, after) { var me = this; if (arguments.length === 1 && !Ext.isFunction(before)) { after = before.after; scope = before.scope; args = before.args; before = before.before; } if (!before || before.apply(scope || me, args || [ me ]) !== false) { var childNodes = me.childNodes, length = childNodes.length, i; for (i = 0; i < length; i++) { childNodes[i].cascadeBy.call(childNodes[i], before, scope, args, after); } if (after) { after.apply(scope || me, args || [ me ]); } } }, eachChild: function(fn, scope, args) { var childNodes = this.childNodes, length = childNodes.length, i; for (i = 0; i < length; i++) { if (fn.apply(scope || this, args || [ childNodes[i] ]) === false) { break; } } }, findChild: function(attribute, value, deep) { return this.findChildBy(function() { return this.get(attribute) == value; }, null, deep); }, 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; }, contains: function(node) { return node.isAncestor(this); }, 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 me = this, childNodes = me.childNodes, ln = childNodes.length, i, n, info = { isFirst: true }; if (ln > 0) { if (!sortFn) { sortFn = me.getTreeStore().getSortFn(); } Ext.Array.sort(childNodes, sortFn); me.setFirstChild(childNodes[0]); me.setLastChild(childNodes[ln - 1]); for (i = 0; i < ln; i++) { n = childNodes[i]; n.previousSibling = childNodes[i - 1]; n.nextSibling = childNodes[i + 1]; info.isLast = (i === ln - 1); info.index = i; n.updateInfo(false, info); info.isFirst = false; if (recursive && !n.isLeaf()) { n.sort(sortFn, true, true); } } if (suppressEvent !== true) { me.fireEventArgs('sort', [ me, childNodes ]); me.callTreeStore('onNodeSort', [ childNodes ]); } } }, isExpanded: function() { return this.get('expanded'); }, isLoaded: function() { return this.get('loaded'); }, isBranchLoaded: function() { var isBranchLoaded = !this.isLeaf() && this.isLoaded(); if (isBranchLoaded) { this.cascadeBy(function(node) { if (!node.isLeaf()) { isBranchLoaded = isBranchLoaded || node.isBranchLoaded(); } return isBranchLoaded; }); } return isBranchLoaded; }, 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, treeStore, resumeAddEvent; if (!me.isLeaf()) { if (me.isLoading()) { me.on('expand', function() { me.expand(recursive, callback, scope); }, me, { single: true }); } else { if (!me.isExpanded()) { if (me.fireEventArgs('beforeexpand', [ me ]) !== false) { if (recursive) { if (me.parentNode && me.parentNode.isSynchronousRecursiveExpand) { me.isSynchronousRecursiveExpand = true; } else { treeStore = me.getTreeStore(); if (treeStore.getProxy().isSynchronous || me.isBranchLoaded()) { me.isSynchronousRecursiveExpand = true; treeStore.suspendEvent('add'); resumeAddEvent = true; } } } me.callTreeStore('onBeforeNodeExpand', [ me.onChildNodesAvailable, me, [ recursive, callback, scope ] ]); if (resumeAddEvent) { treeStore.resumeEvent('add'); treeStore.fireEvent('refresh', treeStore); } me.isSynchronousRecursiveExpand = false; } } else if (recursive) { me.expandChildren(true, callback, scope); } else { Ext.callback(callback, scope || me, [ me.childNodes ]); } } } else { Ext.callback(callback, scope || me); } }, onChildNodesAvailable: function(records, recursive, callback, scope) { var me = this, treeStore = me.getTreeStore(), bulkUpdate = treeStore && treeStore.bulkUpdate, ancestor, i, collapsedAncestors; Ext.suspendLayouts(); for (ancestor = me.parentNode; ancestor; ancestor = ancestor.parentNode) { if (!ancestor.isExpanded()) { (collapsedAncestors || (collapsedAncestors = [])).unshift(ancestor); } } if (bulkUpdate) { me.data.expanded = true; } else { me.set('expanded', true); } if (collapsedAncestors) { for (i = 1; i < collapsedAncestors.length; i++) { ancestor = collapsedAncestors[i]; if (bulkUpdate) { ancestor.data.expanded = true; } else { ancestor.set('expanded', true); } } collapsedAncestors[0].expand(); for (i = 1; i < collapsedAncestors.length; i++) { ancestor = collapsedAncestors[i]; ancestor.fireEventArgs('expand', [ ancestor, ancestor.childNodes ]); } } else { me.callTreeStore('onNodeExpand', [ records, false ]); } me.fireEventArgs('expand', [ me, records ]); if (recursive) { me.expandChildren(true, callback, scope); } else { Ext.callback(callback, scope || me, [ me.childNodes ]); } Ext.resumeLayouts(true); }, expandChildren: function(recursive, callback, scope, singleExpand) { var me = this, origCallback, i, allNodes, expandNodes, ln, node, treeStore; if (Ext.isBoolean(callback)) { origCallback = callback; callback = scope; scope = singleExpand; singleExpand = origCallback; } if (singleExpand === undefined) { treeStore = me.getTreeStore(); singleExpand = treeStore && treeStore.singleExpand; } allNodes = me.childNodes; expandNodes = []; ln = singleExpand ? Math.min(allNodes.length, 1) : allNodes.length; for (i = 0; i < ln; ++i) { node = allNodes[i]; if (!node.isLeaf()) { expandNodes[expandNodes.length] = node; } } ln = expandNodes.length; for (i = 0; i < ln; ++i) { expandNodes[i].expand(recursive); } if (callback) { Ext.callback(callback, scope || me, [ me.childNodes ]); } }, collapse: function(recursive, callback, scope) { var me = this, expanded = me.isExpanded(), treeStore = me.getTreeStore(), bulkUpdate = treeStore && treeStore.bulkUpdate, len = me.childNodes.length, i, collapseChildren; if (!me.isLeaf() && ((!expanded && recursive) || me.fireEventArgs('beforecollapse', [ me ]) !== false)) { Ext.suspendLayouts(); if (me.isExpanded()) { if (recursive) { collapseChildren = function() { for (i = 0; i < len; i++) { me.childNodes[i].setCollapsed(true); } }; if (callback) { callback = Ext.Function.createSequence(collapseChildren, Ext.Function.bind(callback, scope, [ me.childNodes ])); } else { callback = collapseChildren; } } else if (callback) { callback = Ext.Function.bind(callback, scope, [ me.childNodes ]); } if (bulkUpdate) { me.data.expanded = false; } else { me.set('expanded', false); } me.callTreeStore('onNodeCollapse', [ me.childNodes, callback, scope ]); me.fireEventArgs('collapse', [ me, me.childNodes ]); callback = null; } else if (recursive) { for (i = 0; i < len; i++) { me.childNodes[i].setCollapsed(true); } } Ext.resumeLayouts(true); } Ext.callback(callback, scope || me, [ me.childNodes ]); }, setCollapsed: function(recursive) { var me = this, len = me.childNodes.length, i; if (!me.isLeaf() && me.fireEventArgs('beforecollapse', [ me ]) !== false) { me.data.expanded = false; me.fireEventArgs('collapse', [ me, me.childNodes ]); if (recursive) { for (i = 0; i < len; i++) { me.childNodes[i].setCollapsed(true); } } } }, collapseChildren: function(recursive, callback, scope) { var me = this, i, allNodes = me.childNodes, ln = allNodes.length, collapseNodes = [], node; for (i = 0; i < ln; ++i) { node = allNodes[i]; if (!node.isLeaf() && node.isLoaded() && node.isExpanded()) { collapseNodes.push(node); } } ln = collapseNodes.length; if (ln) { for (i = 0; i < ln; ++i) { node = collapseNodes[i]; if (i === ln - 1) { node.collapse(recursive, callback, scope); } else { node.collapse(recursive); } } } else { Ext.callback(callback, scope); } }, fireEvent: function(eventName) { return this.fireEventArgs(eventName, Ext.Array.slice(arguments, 1)); }, fireEventArgs: function(eventName, args) { var fireEventArgs = Ext.mixin.Observable.prototype.fireEventArgs, result, eventSource, topNode; if (bubbledEvents[eventName]) { for (eventSource = this; result !== false && eventSource; eventSource = (topNode = eventSource).parentNode) { if (eventSource.hasListeners && eventSource.hasListeners[eventName]) { result = fireEventArgs.call(eventSource, eventName, args); } } if (result !== false) { eventSource = topNode.getTreeStore(); if (eventSource && eventSource.hasListeners && eventSource.hasListeners[eventName = 'node' + eventName]) { result = eventSource.fireEventArgs(eventName, args); } } return result; } else { return fireEventArgs.apply(this, arguments); } }, serialize: function(writerParam) { var writer = writerParam || new Ext.data.writer.Json({ writeAllFields: true }), result = writer.getRecordData(this), childNodes = this.childNodes, len = childNodes.length, children, i; if (len > 0) { result.children = children = []; for (i = 0; i < len; i++) { children.push(childNodes[i].serialize(writer)); } } return result; }, callTreeStore: function(funcName, args) { var me = this, target = me.getTreeStore(), fn = target && target[funcName]; if (target && fn) { args = args || []; if (args[0] !== me) { args.unshift(me); } fn.apply(target, args); } }, privates: { join: function(store) { if (store.isTreeStore) { if (this.isRoot()) { this.treeStore = this.store = store; } } else { this.callParent([ store ]); } }, callJoined: function(funcName, args) { this.callParent([ funcName, args ]); this.callTreeStore(funcName, args); } } }; } } }); Ext.define('Ext.data.NodeStore', { extend: 'Ext.data.Store', alias: 'store.node', requires: [ 'Ext.data.NodeInterface' ], isNodeStore: true, config: { node: null, recursive: false, rootVisible: false, folderSort: false }, isExpandingOrCollapsing: 0, getTotalCount: function() { return this.getCount(); }, afterEdit: function(record, modifiedFields) { if (this.getNode() && modifiedFields) { if (Ext.Array.indexOf(modifiedFields, 'loaded') !== -1) { return this.add(this.retrieveChildNodes(record)); } if (Ext.Array.indexOf(modifiedFields, 'expanded') !== -1) { return this.filter(); } if (Ext.Array.indexOf(modifiedFields, 'sorted') !== -1) { return this.sort(); } } this.callParent(arguments); }, afterReject: function(record) { var me = this; if (me.contains(record)) { me.onUpdate(record, Ext.data.Model.REJECT, null); me.fireEvent('update', me, record, Ext.data.Model.REJECT, null); } }, afterCommit: function(record, modifiedFieldNames) { var me = this; if (!modifiedFieldNames) { modifiedFieldNames = null; } if (me.contains(record)) { me.onUpdate(record, Ext.data.Model.COMMIT, modifiedFieldNames); me.fireEvent('update', me, record, Ext.data.Model.COMMIT, modifiedFieldNames); } }, onNodeAppend: function(parent, node) { this.add([ node ].concat(this.retrieveChildNodes(node))); }, onNodeInsert: function(parent, node) { this.add([ node ].concat(this.retrieveChildNodes(node))); }, onNodeRemove: function(parent, node) { this.remove([ node ].concat(this.retrieveChildNodes(node))); }, onNodeExpand: function(parent, records) { this.loadRecords(records); }, applyNode: function(node) { if (node) { Ext.data.NodeInterface.decorate(node); } return node; }, updateNode: function(node, oldNode) { var me = this, data; if (oldNode && !oldNode.isDestroyed) { oldNode.un({ append: 'onNodeAppend', insert: 'onNodeInsert', remove: 'onNodeRemove', load: 'onNodeLoad', scope: me }); oldNode.unjoin(me); } if (node) { node.on({ scope: me, append: 'onNodeAppend', insert: 'onNodeInsert', remove: 'onNodeRemove', load: 'onNodeLoad' }); node.join(me); data = []; if (node.childNodes.length) { data = data.concat(me.retrieveChildNodes(node)); } if (me.getRootVisible()) { data.push(node); } else if (node.isLoaded() || node.isLoading()) { node.set('expanded', true); } me.getData().clear(); me.fireEvent('clear', me); me.suspendEvents(); me.add(data); me.resumeEvents(); if (data.length === 0) { me.loaded = node.loaded = true; } me.fireEvent('refresh', me, me.data); } }, retrieveChildNodes: function(root) { var node = this.getNode(), recursive = this.getRecursive(), added = [], child = root; if (!root.childNodes.length || (!recursive && root !== node)) { return added; } if (!recursive) { return root.childNodes; } while (child) { if (child._added) { delete child._added; if (child === root) { break; } else { child = child.nextSibling || child.parentNode; } } else { if (child !== root) { added.push(child); } if (child.firstChild) { child._added = true; child = child.firstChild; } else { child = child.nextSibling || child.parentNode; } } } return added; }, isVisible: function(node) { var parent = node.parentNode; if (!this.getRecursive() && parent !== this.getNode()) { return false; } while (parent) { if (!parent.isExpanded()) { return false; } if (parent === this.getNode()) { break; } parent = parent.parentNode; } return true; } }); Ext.define('Ext.data.Request', { config: { action: undefined, params: undefined, method: 'GET', url: null, operation: null, proxy: null, disableCaching: false, headers: {}, callbackKey: null, rawRequest: null, jsonData: undefined, xmlData: undefined, withCredentials: false, username: null, password: null, binary: false, callback: null, scope: null, timeout: 30000, records: null, directFn: null, args: null, useDefaultXhrHeader: null }, constructor: function(config) { this.initConfig(config); }, getParam: function(key) { var params = this.getParams(), val; if (params) { return params[key]; } return val; }, setParam: function(key, value) { var params = this.getParams() || {}; params[key] = value; this.setParams(params); } }); Ext.define('Ext.mixin.Queryable', { mixinId: 'queryable', isQueryable: true, query: function(selector) { selector = selector || '*'; return Ext.ComponentQuery.query(selector, this.getQueryRoot()); }, queryBy: function(fn, scope) { var out = [], items = this.getQueryRoot().getRefItems(true), i = 0, len = items.length, item; for (; i < len; ++i) { item = items[i]; if (fn.call(scope || item, item) !== false) { out.push(item); } } return out; }, queryById: function(id) { return this.down(Ext.makeIdSelector(id)); }, child: function(selector) { var children = this.getQueryRoot().getRefItems(); if (selector && selector.isComponent) { return this.matchById(children, selector.getItemId()); } if (selector) { children = Ext.ComponentQuery.query(selector, children); } if (children.length) { return children[0]; } return null; }, down: function(selector) { if (selector && selector.isComponent) { return this.matchById(this.getRefItems(true), selector.getItemId()); } selector = selector || ''; return this.query(selector)[0] || null; }, visitPreOrder: function(selector, fn, scope, extraArgs) { Ext.ComponentQuery._visit(true, selector, this.getQueryRoot(), fn, scope, extraArgs); }, visitPostOrder: function(selector, fn, scope, extraArgs) { Ext.ComponentQuery._visit(false, selector, this.getQueryRoot(), fn, scope, extraArgs); }, getRefItems: function() { return []; }, getQueryRoot: function() { return this; }, privates: { matchById: function(items, id) { var len = items.length, i, item; for (i = 0; i < len; ++i) { item = items[i]; if (item.getItemId() === id) { return item; } } return null; } } }); Ext.define('Ext.data.TreeModel', { extend: 'Ext.data.Model', requires: [ 'Ext.data.NodeInterface' ], mixins: [ 'Ext.mixin.Queryable' ], getRefItems: function() { return this.childNodes; }, getRefOwner: function() { return this.parentNode; } }, function() { Ext.data.NodeInterface.decorate(this); }); Ext.define('Ext.data.TreeStore', { extend: 'Ext.data.NodeStore', alias: 'store.tree', requires: [ 'Ext.util.Sorter', 'Ext.data.TreeModel', 'Ext.data.NodeInterface' ], isTreeStore: true, config: { root: null, rootVisible: false, recursive: true, defaultRootProperty: 'children', parentIdProperty: null, clearOnLoad: true, clearRemovedOnLoad: true, nodeParam: 'node', defaultRootId: 'root', defaultRootText: 'Root', folderSort: false }, lazyFill: false, fillCount: 0, bulkUpdate: 0, _silentOptions: { silent: true }, constructor: function(config) { var me = this; me.byIdMap = {}; me.callParent([ config ]); 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; } }, applyFields: function(fields) { var me = this; if (fields) { if (me.defaultRootProperty !== me.self.prototype.config.defaultRootProperty) { fields = fields.concat({ name: me.defaultRootProperty, type: 'auto', defaultValue: null, persist: false }); } me.setModel(Ext.define(null, { extend: 'Ext.data.TreeModel', fields: fields, proxy: me.getProxy() })); me.implicitModel = true; } }, onSorterEndUpdate: function() { var me = this, sorterCollection = me.getSorters(), sorters = sorterCollection.getRange(), rootNode = me.getRoot(), folderSort = me.getFolderSort(); if (rootNode && (folderSort || sorters.length)) { if (me.getRemoteSort()) { if (sorters.length) { me.attemptLoad({ callback: function() { me.fireEvent('sort', me, sorters); } }); } } else { rootNode.sort(this.getSortFn(), true); me.fireEvent('datachanged', me); me.fireEvent('refresh', me); me.fireEvent('sort', me, sorters); } } else { me.fireEvent('sort', me, sorters); } }, updateFolderSort: function(folderSort) { this.needsFolderSort = folderSort; this.onSorterEndUpdate(); }, getSortFn: function() { return this._sortFn || (this._sortFn = this.createSortFn()); }, createSortFn: function() { var me = this, sortersSortFn = this.sorters.getSortFn(); return function(node1, node2) { var node1FolderOrder, node2FolderOrder, result = 0; if (me.needsFolderSort) { node1FolderOrder = node1.data.leaf ? 1 : 0; node2FolderOrder = node2.data.leaf ? 1 : 0; result = node1FolderOrder - node2FolderOrder; } if (me.needsIndexSort && result === 0) { result = node1.data.index - node2.data.index; } return result || sortersSortFn(node1, node2); }; }, afterEdit: function(node, modifiedFieldNames) { var me = this; if (me.needsLocalFilter()) { me.doFilter(node); } me.callParent([ node, modifiedFieldNames ]); }, fireChangeEvent: function(record) { return !!this.byIdMap[record.id]; }, updateRootVisible: function(rootVisible) { var rootNode = this.getRoot(), data; if (rootNode) { data = this.getData(); if (rootVisible) { data.insert(0, rootNode); } else { data.remove(rootNode); } } }, updateTrackRemoved: function(trackRemoved) { this.callParent(arguments); this.removedNodes = this.removed; this.removed = null; }, getRemovedRecords: function() { return this.removedNodes; }, onDestroyRecords: function(records, operation, success) { if (success) { this.removedNodes.length = 0; } }, updateProxy: function(proxy) { var reader; if (proxy) { if (proxy.setIdParam) { proxy.setIdParam(this.getNodeParam()); } reader = proxy.getReader(); if (Ext.isEmpty(reader.getRootProperty())) { reader.setRootProperty(this.getDefaultRootProperty()); } } }, setProxy: function(proxy) { this.changingProxy = true; this.callParent([ proxy ]); this.changingProxy = false; }, applyModel: function(model) { return this.callParent(arguments) || Ext.data.TreeModel; }, updateModel: function(model) { var isNode = model.prototype.isNode; Ext.data.NodeInterface.decorate(model); if (!isNode && !this.changingProxy) { this.getProxy().getReader().buildExtractors(true); } }, onFilterEndUpdate: function(filters) { var me = this, length = filters.length, root = me.getRoot(), childNodes, childNode, filteredNodes, i; if (!me.getRemoteFilter()) { if (length) { me.doFilter(root); } else { root.cascadeBy({ after: function(node) { node.set('visible', true, me._silentOptions); } }); } if (length) { filteredNodes = []; childNodes = root.childNodes; for (i = 0 , length = childNodes.length; i < length; i++) { childNode = childNodes[i]; if (childNode.get('visible')) { filteredNodes.push(childNode); } } } else { filteredNodes = root.childNodes; } me.onNodeFilter(root, filteredNodes); root.fireEvent('filterchange', root, filteredNodes); me.fireEvent('filterchange', me, filters); me.suppressNextFilter = true; me.callParent([ filters ]); me.suppressNextFilter = false; } else { me.callParent([ filters ]); } }, onNodeFilter: function(root, childNodes) { var me = this, data = me.getData(), toAdd = []; if (me.getRootVisible()) { if (childNodes.length) { toAdd.push(root); } else { root.set('visible', false, me._silentOptions); } } me.handleNodeExpand(root, childNodes, toAdd); me.suspendEvents(); data.splice(0, data.getCount(), toAdd); me.resumeEvents(); if (!me.suppressNextFilter) { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); } }, onBeforeNodeExpand: function(node, callback, scope, args) { var me = this, storeReader, nodeProxy, nodeReader, reader, children, callbackArgs; if (node.isLoaded()) { callbackArgs = [ node.childNodes ]; if (args) { callbackArgs.push.apply(callbackArgs, args); } Ext.callback(callback, scope || node, callbackArgs); } else if (node.isLoading()) { me.on('load', function() { callbackArgs = [ node.childNodes ]; if (args) { callbackArgs.push.apply(callbackArgs, args); } Ext.callback(callback, scope || node, callbackArgs); }, me, { single: true, priority: 1001 }); } else { storeReader = me.getProxy().getReader(); nodeProxy = node.getProxy(); nodeReader = nodeProxy ? nodeProxy.getReader() : null; reader = nodeReader && nodeReader.initialConfig.rootProperty ? nodeReader : storeReader; children = reader.getRoot(node.raw || node.data); if (children || (node.phantom && !node.isRoot())) { if (children) { me.fillNode(node, reader.extractData(children, { model: node.childType, recordCreator: me.recordCreator })); } callbackArgs = [ node.childNodes ]; if (args) { callbackArgs.push.apply(callbackArgs, args); } Ext.callback(callback, scope || node, callbackArgs); } else { if (node.isRoot()) { me.clearLoadTask(); } me.read({ node: node, onChildNodesAvailable: function() { delete me.lastOptions.onChildNodesAvailable; callbackArgs = [ node.childNodes ]; if (args) { callbackArgs.push.apply(callbackArgs, args); } Ext.callback(callback, scope || node, callbackArgs); } }); } } }, onNodeExpand: function(parent, records) { var me = this, insertIndex = me.indexOf(parent) + 1, toAdd = []; me.handleNodeExpand(parent, records, toAdd); if (!me.refreshCounter && parent.isRoot() && !parent.get('visible')) { me.loadRecords(toAdd); } else { me.insert(insertIndex, toAdd); } }, handleNodeExpand: function(parent, records, toAdd) { var me = this, ln = records ? records.length : 0, i, record; if (parent !== this.getRoot() && !me.isVisible(parent)) { return; } if (ln) { for (i = 0; i < ln; i++) { record = records[i]; if (record.get('visible')) { toAdd.push(record); if (record.isExpanded()) { if (record.isLoaded()) { me.handleNodeExpand(record, record.childNodes, toAdd); } else { record.set('expanded', false); record.expand(); } } } } } }, onNodeCollapse: function(parent, records, callback, scope) { var me = this, collapseIndex = me.indexOf(parent) + 1, lastNodeIndexPlus; if (!me.recursive && parent !== me.getRoot()) { return; } if (me.needsLocalFilter()) { records = Ext.Array.filter(records, me.filterVisible); } if (records.length && me.data.contains(records[0])) { lastNodeIndexPlus = me.indexOfNextVisibleNode(parent); me.removeAt(collapseIndex, lastNodeIndexPlus - collapseIndex); } Ext.callback(callback, scope); }, indexOfNextVisibleNode: function(node) { var result; while (node.parentNode) { for (result = node.nextSibling; result && !result.get('visible'); result = result.nextSibling) {} if (result) { return this.indexOf(result); } node = node.parentNode; } return this.getCount(); }, filterNew: function(item) { return !item.get('root') && this.callParent([ item ]); }, filterRejects: function(item) { return !item.get('root') && this.callParent([ item ]); }, getNewRecords: function() { return Ext.Array.filter(Ext.Object.getValues(this.byIdMap), this.filterNew, this); }, getUpdatedRecords: function() { return Ext.Array.filter(Ext.Object.getValues(this.byIdMap), this.filterUpdated); }, beforeNodeRemove: function(parentNode, childNodes) { if (!Ext.isArray(childNodes)) { childNodes = [ childNodes ]; } var me = this, len = childNodes.length, i, startNode; for (i = 0; !startNode && i < len; i++) { if (childNodes[i].get('visible')) { startNode = childNodes[i]; } } if (startNode) { me.startRemoveIndex = me.indexOf(childNodes[0]); me.lastRemoveIndexPlusOne = me.indexOfNextVisibleNode(childNodes[childNodes.length - 1]); } else { me.startRemoveIndex = -1; me.lastRemoveIndexPlusOne = 0; } }, afterDrop: Ext.emptyFn, onNodeRemove: function(parentNode, childNodes, isMove) { var me = this, removed = me.removedNodes, len = childNodes.length, startRemoveIndex = me.startRemoveIndex, lastRemoveIndexPlusOne = me.lastRemoveIndexPlusOne, i; me.suspendAutoSync(); if (startRemoveIndex !== -1) { me.removeIsMove = isMove; me.removeAt(startRemoveIndex, lastRemoveIndexPlusOne - startRemoveIndex); me.removeIsMove = false; } for (i = 0; i < len; i++) { childNodes[i].cascadeBy(function(node) { me.unregisterNode(node); if (removed && !isMove) { if (!node.phantom && !node.erasing && !me.loading) { node.removedFrom = me.indexOf(node); removed.push(node); me.needsSync = true; } } }); } me.resumeAutoSync(); }, onNodeAppend: function(parent, node, index) { this.onNodeInsert(parent, node, index); }, onNodeInsert: function(parent, node, index) { var me = this, data = node.raw || node.data, refNode, sibling, storeReader, nodeProxy, nodeReader, reader, dataRoot; if (parent && me.needsLocalFilter()) { me.doFilter(parent); } me.beginUpdate(); if (me.isVisible(node)) { if (index === 0 || !node.previousSibling) { refNode = parent; } else { for (sibling = node.previousSibling; sibling && !sibling.get('visible'); sibling = sibling.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); } else if (!me.fillCount) { node.set('expanded', false); node.expand(); } } } me.needsSync = me.needsSync || node.phantom || node.dirty; if (!node.isLeaf() && !node.isLoaded() && !me.lazyFill) { storeReader = me.getProxy().getReader(); nodeProxy = node.getProxy(); nodeReader = nodeProxy ? nodeProxy.getReader() : null; reader = nodeReader && nodeReader.initialConfig.rootProperty ? nodeReader : storeReader; dataRoot = reader.getRoot(data); if (dataRoot) { me.fillNode(node, reader.extractData(dataRoot, { model: node.childType, recordCreator: me.recordCreator })); } } me.endUpdate(); }, registerNode: function(node, includeChildren) { var me = this, children, length, i; me.byIdMap[node.id] = node; if (includeChildren === true) { children = node.childNodes; length = children.length; for (i = 0; i < length; i++) { me.registerNode(children[i], true); } } }, unregisterNode: function(node, includeChildren) { var me = this, children, length, i; delete me.byIdMap[node.id]; if (includeChildren === true) { children = node.childNodes; length = children.length; for (i = 0; i < length; i++) { me.unregisterNode(children[i], true); } } }, onNodeSort: function(node, childNodes) { var me = this; me.suspendAutoSync(); if ((me.indexOf(node) !== -1 || (node === me.getRoot() && !me.getRootVisible()) && node.isExpanded())) { Ext.suspendLayouts(); me.onNodeCollapse(node, childNodes); me.onNodeExpand(node, childNodes); Ext.resumeLayouts(true); } me.resumeAutoSync(me.autoSync); }, applyRoot: function(newRoot) { var me = this, Model = me.getModel(), idProperty = Model.prototype.idProperty, defaultRootId = me.getDefaultRootId(); if (newRoot && !newRoot.isNode) { newRoot = Ext.apply({ text: me.getDefaultRootText(), root: true, isFirst: true, isLast: true, depth: 0, index: 0, parentId: null, allowDrag: false }, newRoot); if (defaultRootId && newRoot[idProperty] === undefined) { newRoot[idProperty] = defaultRootId; } newRoot = new Model(newRoot); newRoot.store = newRoot.treeStore = me; } return newRoot; }, updateRoot: function(newRoot, oldRoot) { var me = this, oldOwner, initial = !oldRoot, toRemove; me.byIdMap = {}; me.getTrackRemoved(); me.suspendEvent('add', 'remove'); if (oldRoot && oldRoot.isModel) { if (me.rootVisible) { toRemove = [ oldRoot ]; } else { toRemove = oldRoot.childNodes; } me.beforeNodeRemove(null, toRemove); oldRoot.set('root', false); me.onNodeRemove(null, toRemove); oldRoot.fireEvent('remove', null, oldRoot, false); oldRoot.fireEvent('rootchange', null); oldRoot.clearListeners(); oldRoot.store = oldRoot.treeStore = null; } me.getData().clear(); if (newRoot) { if (newRoot.fireEventArgs('beforeappend', [ null, newRoot ]) === false) { newRoot = null; } else { oldOwner = newRoot.parentNode; if (oldOwner) { if (!oldOwner.removeChild(newRoot, false, false, oldOwner.getTreeStore() === me)) { return; } } else if ((oldOwner = newRoot.getTreeStore()) && oldOwner !== me && newRoot === oldOwner.getRoot()) { oldOwner.setRoot(null); } newRoot.set('root', true); newRoot.updateInfo(true, { isFirst: true, isLast: true, depth: 0, index: 0, parentId: null }); me.registerNode(newRoot, true); newRoot.fireEvent('append', null, newRoot, false); newRoot.fireEvent('rootchange', newRoot); me.onNodeAppend(null, newRoot, 0); newRoot.phantom = true; } } me.fireEvent('rootchange', newRoot, oldRoot); if (newRoot && (me.getAutoLoad() || newRoot.isExpanded())) { if (newRoot.isLoaded()) { me.onNodeExpand(newRoot, newRoot.childNodes); me.fireEvent('datachanged', me); me.fireEvent('refresh', me); } else { newRoot.data.expanded = false; newRoot.expand(false, function() { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); }); } } else if (!initial) { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); } me.resumeEvent('add', 'remove'); return newRoot; }, getNodeById: function(id) { return this.byIdMap[id] || null; }, findNode: function(property, value, startsWith, endsWith, ignoreCase) { if (Ext.isEmpty(value, false)) { return null; } if (value === this.model.idProperty && arguments.length < 3) { return this.byIdMap[value]; } var regex = Ext.String.createRegex(value, startsWith, endsWith, ignoreCase), result = null; Ext.Object.eachValue(this.byIdMap, function(node) { if (node && regex.test(node.get(property))) { result = node; return false; } }); return result; }, load: function(options) { options = options || {}; options.params = options.params || {}; var me = this, node = options.node || me.getRoot(), callback = options.callback, scope = options.scope, clearOnLoad = me.getClearOnLoad(), isReload = node && node.isRoot() && node.isLoaded() && clearOnLoad, operation, doClear; if (!node) { me.setRoot({ expanded: true }); return; } if (node.data.expanded && !isReload) { node.data.loaded = false; if (clearOnLoad) { node.data.expanded = false; } options.callback = function(loadedNodes, operation, success) { if (!clearOnLoad) { node.collapse(); } node.expand(); Ext.callback(callback, scope, [ loadedNodes, operation, success ]); }; } options.id = node.getId(); options = Ext.apply({ filters: me.getFilters().items, sorters: me.getSorters().items, node: options.node || node, internalScope: me, internalCallback: me.onProxyLoad }, options); me.lastOptions = Ext.apply({}, options); options.isReload = isReload; operation = me.createOperation('read', options); if (me.fireEvent('beforeload', me, operation) !== false) { me.loading = true; me.clearLoadTask(); if (isReload) { if (me.getClearRemovedOnLoad()) { me.removedNodes.length = 0; } me.unregisterNode(node, true); node.childNodes.length = 0; doClear = true; } else if (clearOnLoad) { if (me.getTrackRemoved() && me.getClearRemovedOnLoad()) { me.clearRemoved(node); } node.removeAll(false); } if (me.loading && node) { node.set('loading', true); } if (doClear) { me.clearData(true); if (me.getRootVisible()) { me.suspendEvents(); me.add(node); me.resumeEvents(); } } operation.execute(); } return me; }, onProxyLoad: function(operation) { var me = this, options = operation.initialConfig, successful = operation.wasSuccessful(), records = operation.getRecords(), node = options.node, isReload = options.isReload, scope = operation.getScope() || me, args = [ records, operation, successful ]; if (me.isDestroyed) { return; } me.loading = false; node.set('loading', false); if (successful) { ++me.loadCount; if (!me.getClearOnLoad()) { records = me.cleanRecords(node, records); } if (me.getParentIdProperty()) { records = me.treeify(node, records); } if (isReload) { me.suspendEvent('add', 'update'); } records = me.fillNode(node, records); } if (isReload) { me.resumeEvent('add', 'update'); me.callObservers('BeforePopulate'); me.fireEvent('datachanged', me); me.fireEvent('refresh', me); me.callObservers('AfterPopulate'); } else { Ext.callback(options.onChildNodesAvailable, scope, args); } me.fireEvent('load', me, records, successful, operation, node); }, clearRemoved: function(node) { var me = this, removed = me.removedNodes, id = node.getId(), removedLength = removed.length, i = removedLength, recordsToClear = {}, newRemoved = [], removedHash = {}, removedNode, targetNode, targetId; if (node === me.getRoot()) { me.removedNodes.length = 0; return; } for (; i--; ) { removedNode = removed[i]; removedHash[removedNode.getId()] = removedNode; } for (i = removedLength; i--; ) { removedNode = removed[i]; targetNode = removedNode; while (targetNode && targetNode.getId() !== id) { targetId = targetNode.get('parentId') || targetNode.get('lastParentId'); targetNode = targetNode.parentNode || me.getNodeById(targetId) || removedHash[targetId]; } if (targetNode) { recordsToClear[removedNode.getId()] = removedNode; } } for (i = 0; i < removedLength; i++) { removedNode = removed[i]; if (!recordsToClear[removedNode.getId()]) { newRemoved.push(removedNode); } } me.removedNodes = newRemoved; }, fillNode: function(node, newNodes) { var me = this, newNodeCount = newNodes ? newNodes.length : 0, sorters = me.getSorters(), needsIndexSort = false, performLocalSort = me.sortOnLoad && newNodeCount > 1 && !me.getRemoteSort() && me.getFolderSort() || sorters.length, node1, node2, i, filterFn; ++me.bulkUpdate; if (newNodeCount) { if (me.needsLocalFilter()) { filterFn = me.getFilters().getFilterFn(); newNodes[0].set('visible', filterFn(newNodes[0])); } for (i = 1; i < newNodeCount; i++) { node1 = newNodes[i]; node2 = newNodes[i - 1]; if (filterFn) { node1.set('visible', filterFn(node1)); } needsIndexSort = node1.data.index !== node2.data.index; } if (performLocalSort) { me.needsIndexSort = true; Ext.Array.sort(newNodes, me.getSortFn()); me.needsIndexSort = false; } else if (needsIndexSort) { Ext.Array.sort(newNodes, me.sortByIndex); } } if (me.bulkUpdate === 1) { node.set('loaded', true); } else { node.data.loaded = true; } if (newNodes.length) { node.appendChild(newNodes, undefined, true); } --me.bulkUpdate; return newNodes; }, beginFill: function() { var me = this; if (!me.fillCount++) { me.beginUpdate(); me.suspendEvent('add', 'update'); me.suspendAutoSync(); me.fillArray = []; } }, endFill: function(parent, nodes) { var me = this, fillArray = me.fillArray, i, len, index; fillArray.push(nodes); if (!--me.fillCount) { me.resumeAutoSync(); me.resumeEvent('add', 'update'); for (i = 0 , len = fillArray.length; i < len; i++) { index = me.indexOf(fillArray[i][0]); if (index !== -1) { me.fireEvent('add', me, fillArray[i], index); } } me.fillArray = null; me.endUpdate(); } }, sortByIndex: function(node1, node2) { return node1.data.index - node2.data.index; }, onIdChanged: function(node, oldId, newId) { var childNodes = node.childNodes, len = childNodes && childNodes.length, i; this.callParent(arguments); delete this.byIdMap[oldId]; this.byIdMap[newId] = node; for (i = 0; i < len; i++) { childNodes[i].set('parentId', newId); } }, treeify: function(parentNode, records) { var me = this, loadParentNodeId = parentNode.getId(), parentIdProperty = me.getParentIdProperty(), len = records.length, result = [], nodeMap = {}, i, node, parentId; for (i = 0; i < len; i++) { node = records[i]; nodeMap[node.id] = node; } for (i = 0; i < len; i++) { node = records[i]; parentId = node.data[parentIdProperty]; if (!(parentId || parentId === 0) || parentId === loadParentNodeId) { result.push(node); } else { if (!nodeMap[parentId]) { Ext.raise('Ext.data.TreeStore, Invalid parentId "' + parentId + '"'); } nodeMap[parentId].appendChild(node); } me.registerNode(node); } return result; }, cleanRecords: function(node, records) { var nodeHash = {}, childNodes = node.childNodes, i = 0, len = childNodes.length, out = [], rec; for (; i < len; ++i) { nodeHash[childNodes[i].getId()] = true; } for (i = 0 , len = records.length; i < len; ++i) { rec = records[i]; if (!nodeHash[rec.getId()]) { out.push(rec); } } return out; }, removeAll: function() { this.suspendEvents(); this.setRoot(null); this.resumeEvents(); this.callParent(); }, doSort: function(sorterFn) { var me = this; if (me.getRemoteSort()) { me.load(); } else { me.tree.sort(sorterFn, true); me.fireEvent('datachanged', me); me.fireEvent('refresh', me); } me.fireEvent('sort', me, me.sorters.getRange()); }, filterVisible: function(node) { return node.get('visible'); }, isVisible: function(node) { var parentNode = node.parentNode, visible = node.data.visible, root = this.getRoot(); while (visible && parentNode) { visible = parentNode.data.expanded && parentNode.data.visible; parentNode = parentNode.parentNode; } return visible && !(node === root && !this.getRootVisible()); }, commitChanges: function() { var removed = this.removedNodes; if (removed) { removed.length = 0; } this.callParent(); }, getRootNode: function() { return this.getRoot(); }, setRootNode: function(root) { this.setRoot(root); return this.getRoot(); }, privates: { recordCreator: function(data, Model) { return new Model(data); }, doFilter: function(node) { var root = this.getRoot(), filterFn = this.getFilters().getFilterFn(); this.filterNodes(root, node, filterFn); }, filterNodes: function(root, node, filterFn) { var match = false, childNodes = node.childNodes, len = childNodes && childNodes.length, i; if (len) { for (i = 0; i < len; ++i) { this.filterNodes(root, childNodes[i], filterFn); } } match = node === root || filterFn(node); node.set('visible', match, this._silentOptions); return match; }, needsLocalFilter: function() { return !this.getRemoteFilter() && this.getFilters().length; }, onRemoteFilterSet: function(filters, remoteFilter) { var data = this.getData(); data.setFilters(null); if (filters) { filters.on('endupdate', this.onFilterEndUpdate, this); } }, onRemoteSortSet: function(sorters, remoteSort) { var data = this.getData(); data.setSorters(null); if (sorters) { sorters.on('endupdate', this.onSorterEndUpdate, this); } } }, deprecated: { 5: { properties: { tree: null } } } }); Ext.define('Ext.data.Types', { singleton: true, requires: [ 'Ext.data.SortTypes' ] }, function(Types) { var SortTypes = Ext.data.SortTypes; Ext.apply(Types, { stripRe: /[\$,%]/g, AUTO: { sortType: SortTypes.none, type: 'auto' }, STRING: { convert: function(v) { var defaultValue = this.getAllowNull() ? null : ''; return (v === undefined || v === null) ? defaultValue : String(v); }, sortType: SortTypes.asUCString, type: 'string' }, INT: { convert: function(v) { if (typeof v === 'number') { return parseInt(v, 10); } return v !== undefined && v !== null && v !== '' ? parseInt(String(v).replace(Types.stripRe, ''), 10) : (this.getAllowNull() ? null : 0); }, sortType: SortTypes.none, type: 'int' }, FLOAT: { convert: function(v) { if (typeof v === 'number') { return v; } return v !== undefined && v !== null && v !== '' ? parseFloat(String(v).replace(Types.stripRe, ''), 10) : (this.getAllowNull() ? null : 0); }, sortType: SortTypes.none, type: 'float' }, BOOL: { convert: function(v) { if (typeof v === 'boolean') { return v; } if (this.getAllowNull() && (v === undefined || v === null || v === '')) { return null; } return v === 'true' || v == 1; }, sortType: SortTypes.none, type: 'bool' }, DATE: { convert: function(v) { var df = this.getDateReadFormat() || this.getDateFormat(), parsed; if (!v) { return null; } if (v instanceof Date) { return v; } if (df) { return Ext.Date.parse(v, df); } parsed = Date.parse(v); return parsed ? new Date(parsed) : null; }, sortType: SortTypes.asDate, type: 'date' } }); Types.BOOLEAN = Types.BOOL; Types.INTEGER = Types.INT; Types.NUMBER = Types.FLOAT; }); Ext.define('Ext.data.Validation', { extend: 'Ext.data.Model', isValidation: true, syncGeneration: 0, attach: function(record) { this.record = record; delete this.data.id; }, getValidation: function() { return null; }, isValid: function() { var me = this; if (me.syncGeneration !== me.record.generation) { me.refresh(); } return !me.dirty; }, refresh: function(force) { var me = this, data = me.data, record = me.record, fields = record.fields, generation = record.generation, recordData = record.data, sep = record.validationSeparator, values = null, defaultMessage, currentValue, error, field, item, i, j, jLen, len, msg, val, name; if (force || me.syncGeneration !== generation) { me.syncGeneration = generation; for (i = 0 , len = fields.length; i < len; ++i) { field = fields[i]; name = field.name; val = recordData[name]; defaultMessage = field.defaultInvalidMessage; error = 0; if (!(name in data)) { data[name] = currentValue = true; } else { currentValue = data[name]; } if (field.validate !== Ext.emptyFn) { msg = field.validate(val, sep); if (msg !== true) { error = msg || defaultMessage; } } if (!error) { error = true; } if (error !== currentValue) { (values || (values = {}))[name] = error; } } if (values) { me.set(values); } } } }); Ext.define('Ext.dom.Helper', function() { var afterbegin = 'afterbegin', afterend = 'afterend', beforebegin = 'beforebegin', beforeend = 'beforeend', bbValues = [ 'BeforeBegin', 'previousSibling' ], aeValues = [ 'AfterEnd', 'nextSibling' ], bb_ae_PositionHash = { beforebegin: bbValues, afterend: aeValues }, fullPositionHash = { beforebegin: bbValues, afterend: aeValues, afterbegin: [ 'AfterBegin', 'firstChild' ], beforeend: [ 'BeforeEnd', 'lastChild' ] }; return { singleton: true, alternateClassName: [ 'Ext.DomHelper', 'Ext.core.DomHelper' ], emptyTags: /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i, confRe: /^(?:tag|children|cn|html|tpl|tplData)$/i, endRe: /end/i, attributeTransform: { cls: 'class', htmlFor: 'for' }, closeTags: {}, detachedDiv: document.createElement('div'), decamelizeName: function() { var camelCaseRe = /([a-z])([A-Z])/g, cache = {}; function decamel(match, p1, p2) { return p1 + '-' + p2.toLowerCase(); } return function(s) { return cache[s] || (cache[s] = s.replace(camelCaseRe, decamel)); }; }(), generateMarkup: function(spec, buffer) { var me = this, specType = typeof spec, attr, val, tag, i, closeTags; if (specType === "string" || specType === "number") { buffer.push(spec); } else if (Ext.isArray(spec)) { for (i = 0; i < spec.length; i++) { if (spec[i]) { me.generateMarkup(spec[i], buffer); } } } else { tag = spec.tag || 'div'; buffer.push('<', tag); for (attr in spec) { if (spec.hasOwnProperty(attr)) { val = spec[attr]; if (val !== undefined && !me.confRe.test(attr)) { if (typeof val === "object") { buffer.push(' ', attr, '="'); me.generateStyles(val, buffer, true).push('"'); } else { buffer.push(' ', me.attributeTransform[attr] || attr, '="', val, '"'); } } } } if (me.emptyTags.test(tag)) { buffer.push('/>'); } else { buffer.push('>'); if ((val = spec.tpl)) { val.applyOut(spec.tplData, buffer); } if ((val = spec.html)) { buffer.push(val); } if ((val = spec.cn || spec.children)) { me.generateMarkup(val, buffer); } closeTags = me.closeTags; buffer.push(closeTags[tag] || (closeTags[tag] = '')); } } return buffer; }, generateStyles: function(styles, buffer, encode) { var a = buffer || [], name, val; for (name in styles) { if (styles.hasOwnProperty(name)) { val = styles[name]; name = this.decamelizeName(name); if (encode && Ext.String.hasHtmlCharacters(val)) { val = Ext.String.htmlEncode(val); } a.push(name, ':', val, ';'); } } return buffer || a.join(''); }, markup: function(spec) { if (typeof spec === "string") { return spec; } var buf = this.generateMarkup(spec, []); return buf.join(''); }, applyStyles: function(el, styles) { Ext.fly(el).applyStyles(styles); }, createContextualFragment: function(html) { var div = this.detachedDiv, fragment = document.createDocumentFragment(), length, childNodes; div.innerHTML = html; childNodes = div.childNodes; length = childNodes.length; while (length--) { fragment.appendChild(childNodes[0]); } return fragment; }, createDom: function(o, parentNode) { var me = this, markup = me.markup(o), div = me.detachedDiv, child; div.innerHTML = markup; child = div.firstChild; return Ext.supports.ChildContentClearedWhenSettingInnerHTML ? child.cloneNode(true) : child; }, insertHtml: function(where, el, html) { var me = this, hashVal, range, rangeEl, setStart, frag; where = where.toLowerCase(); if (el.insertAdjacentHTML) { if (me.ieInsertHtml) { frag = me.ieInsertHtml(where, el, html); if (frag) { return frag; } } hashVal = fullPositionHash[where]; if (hashVal) { el.insertAdjacentHTML(hashVal[0], html); return el[hashVal[1]]; } } else { if (el.nodeType === 3) { where = where === afterbegin ? beforebegin : where; where = where === beforeend ? afterend : where; } range = Ext.supports.CreateContextualFragment ? el.ownerDocument.createRange() : undefined; setStart = 'setStart' + (this.endRe.test(where) ? 'After' : 'Before'); if (bb_ae_PositionHash[where]) { if (range) { range[setStart](el); frag = range.createContextualFragment(html); } else { frag = this.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) { try { range[setStart](el[rangeEl]); frag = range.createContextualFragment(html); } catch (e) { frag = this.createContextualFragment(html); } } else { frag = this.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.DomHelper', sourceMethod: 'insertHtml', htmlToInsert: html, targetElement: el, msg: 'Illegal insertion point reached: "' + where + '"' }); }, insertBefore: function(el, o, returnElement) { return this.doInsert(el, o, returnElement, beforebegin); }, insertAfter: function(el, o, returnElement) { return this.doInsert(el, o, returnElement, afterend); }, insertFirst: function(el, o, returnElement) { return this.doInsert(el, o, returnElement, afterbegin); }, append: function(el, o, returnElement) { return this.doInsert(el, o, returnElement, beforeend); }, overwrite: function(el, html, returnElement) { var me = this, newNode; el = Ext.getDom(el); html = me.markup(html); if (me.ieOverwrite) { newNode = me.ieOverwrite(el, html); } if (!newNode) { el.innerHTML = html; newNode = el.firstChild; } return returnElement ? Ext.get(newNode) : newNode; }, doInsert: function(el, o, returnElement, where) { var me = this, newNode; el = el.dom || Ext.getDom(el); if ('innerHTML' in el) { newNode = me.insertHtml(where, el, me.markup(o)); } else { newNode = me.createDom(o, null); if (el.nodeType === 3) { where = where === afterbegin ? beforebegin : where; where = where === beforeend ? afterend : where; } if (bb_ae_PositionHash[where]) { el.parentNode.insertBefore(newNode, where === beforebegin ? el : el.nextSibling); } else if (el.firstChild && where === afterbegin) { el.insertBefore(newNode, el.firstChild); } else { el.appendChild(newNode); } } return returnElement ? Ext.get(newNode) : newNode; }, createTemplate: function(o) { var html = this.markup(o); return new Ext.Template(html); }, createHtml: function(spec) { return this.markup(spec); } }; }); Ext.define('Ext.overrides.dom.Helper', (function() { var tableRe = /^(?:table|thead|tbody|tr|td)$/i, tableElRe = /td|tr|tbody|thead/i, ts = '', te = '
', tbs = ts + '', tbe = '' + te, trs = tbs + '', tre = '' + tbe; return { override: 'Ext.dom.Helper', ieInsertHtml: function(where, el, html) { var frag = null; if (Ext.isIE9m && tableRe.test(el.tagName)) { frag = this.insertIntoTable(el.tagName.toLowerCase(), where, el, html); } return frag; }, ieOverwrite: function(el, html) { if (Ext.isIE9m && tableRe.test(el.tagName)) { while (el.firstChild) { el.removeChild(el.firstChild); } if (html) { return this.insertHtml('afterbegin', el, html); } } }, ieTable: function(depth, openingTags, htmlContent, closingTags) { var i = -1, el = this.detachedDiv, ns, nx; el.innerHTML = [ openingTags, htmlContent, closingTags ].join(''); while (++i < depth) { el = el.firstChild; } ns = el.nextSibling; if (ns) { ns = el; el = document.createDocumentFragment(); while (ns) { nx = ns.nextSibling; el.appendChild(ns); ns = nx; } } return el; }, insertIntoTable: function(tag, where, destinationEl, html) { var node, before, bb = where === 'beforebegin', ab = where === 'afterbegin', be = where === 'beforeend', ae = where === 'afterend'; if (tag === 'td' && (ab || be) || !tableElRe.test(tag) && (bb || ae)) { return null; } before = bb ? destinationEl : ae ? destinationEl.nextSibling : ab ? destinationEl.firstChild : null; if (bb || ae) { destinationEl = destinationEl.parentNode; } if (tag === 'td' || (tag === 'tr' && (be || ab))) { node = this.ieTable(4, trs, html, tre); } else if (((tag === 'tbody' || tag === 'thead') && (be || ab)) || (tag === 'tr' && (bb || ae))) { node = this.ieTable(3, tbs, html, tbe); } else { node = this.ieTable(2, ts, html, te); } destinationEl.insertBefore(node, before); return node; } }; })()); Ext.define('Ext.dom.Query', function() { var DQ, doc = document, cache, simpleCache, valueCache, useClassList = !!doc.documentElement.classList, useElementPointer = !!doc.documentElement.firstElementChild, useChildrenCollection = (function() { var d = doc.createElement('div'); d.innerHTML = 'text'; return d.children && (d.children.length === 0); })(), nonSpace = /\S/, trimRe = /^\s+|\s+$/g, tplRe = /\{(\d+)\}/g, modeRe = /^(\s?[\/>+~]\s?|\s|$)/, tagTokenRe = /^(#)?([\w\-\*\|\\]+)/, nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/, startIdRe = /^\s*#/, isIE = window.ActiveXObject ? true : false, key = 30803, longHex = /\\([0-9a-fA-F]{6})/g, shortHex = /\\([0-9a-fA-F]{1,6})\s{0,1}/g, nonHex = /\\([^0-9a-fA-F]{1})/g, escapes = /\\/g, num, hasEscapes, supportsColonNsSeparator = (function() { var xmlDoc, xmlString = ''; if (window.DOMParser) { xmlDoc = (new DOMParser()).parseFromString(xmlString, "application/xml"); } else { xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.loadXML(xmlString); } return !!xmlDoc.getElementsByTagName('a:b').length; })(), longHexToChar = function($0, $1) { return String.fromCharCode(parseInt($1, 16)); }, shortToLongHex = function($0, $1) { while ($1.length < 6) { $1 = '0' + $1; } return '\\' + $1; }, charToLongHex = function($0, $1) { num = $1.charCodeAt(0).toString(16); if (num.length === 1) { num = '0' + num; } return '\\0000' + num; }, unescapeCssSelector = function(selector) { return (hasEscapes) ? selector.replace(longHex, longHexToChar) : selector; }, setupEscapes = function(path) { hasEscapes = (path.indexOf('\\') > -1); if (hasEscapes) { path = path.replace(shortHex, shortToLongHex).replace(nonHex, charToLongHex).replace(escapes, '\\\\'); } return path; }; eval("var batch = 30803, child, next, prev, byClassName;"); child = useChildrenCollection ? function child(parent, index) { return parent.children[index]; } : 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; }; next = useElementPointer ? function(n) { return n.nextElementSibling; } : function(n) { while ((n = n.nextSibling) && n.nodeType != 1){} return n; }; prev = useElementPointer ? function(n) { return n.previousElementSibling; } : function(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; } byClassName = useClassList ? function(nodeSet, cls) { cls = unescapeCssSelector(cls); if (!cls) { return nodeSet; } var result = [], ri = -1, i, ci, classList; for (i = 0; ci = nodeSet[i]; i++) { classList = ci.classList; if (classList) { if (classList.contains(cls)) { result[++ri] = ci; } } else if ((' ' + ci.className + ' ').indexOf(cls) !== -1) { result[++ri] = ci; } } return result; } : function(nodeSet, cls) { cls = unescapeCssSelector(cls); if (!cls) { return nodeSet; } var result = [], ri = -1, i, ci; for (i = 0; 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, i, ni, j, ci, cn, utag, n, cj; if (!ns) { return result; } tagName = tagName.replace('|', ':') || "*"; if (typeof ns.getElementsByTagName != "undefined") { ns = [ ns ]; } if (!mode) { tagName = unescapeCssSelector(tagName); if (!supportsColonNsSeparator && DQ.isXml(ns[0]) && tagName.indexOf(':') !== -1) { for (i = 0; ni = ns[i]; i++) { cs = ni.getElementsByTagName(tagName.split(':').pop()); for (j = 0; ci = cs[j]; j++) { if (ci.tagName === tagName) { result[++ri] = ci; } } } } else { for (i = 0; ni = ns[i]; i++) { cs = ni.getElementsByTagName(tagName); for (j = 0; ci = cs[j]; j++) { result[++ri] = ci; } } } } else if (mode == "/" || mode == ">") { utag = tagName.toUpperCase(); for (i = 0; ni = ns[i]; i++) { cn = ni.childNodes; for (j = 0; cj = cn[j]; j++) { if (cj.nodeName == utag || cj.nodeName == tagName || tagName == '*') { result[++ri] = cj; } } } } else if (mode == "+") { utag = tagName.toUpperCase(); for (i = 0; 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 == "~") { utag = tagName.toUpperCase(); for (i = 0; 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) { a.push.apply(a, b); return a; } function byTag(cs, tagName) { if (cs.tagName || cs === doc) { cs = [ cs ]; } if (!tagName) { return cs; } var result = [], ri = -1, i, ci; tagName = tagName.toLowerCase(); for (i = 0; ci = cs[i]; i++) { if (ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName) { result[++ri] = ci; } } return result; } function byId(cs, id) { id = unescapeCssSelector(id); if (cs.tagName || cs === doc) { cs = [ cs ]; } if (!id) { return cs; } var result = [], ri = -1, i, ci; for (i = 0; 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 = DQ.operators[op], a, xml, hasXml, i, ci; value = unescapeCssSelector(value); for (i = 0; ci = cs[i]; i++) { if (ci.nodeType === 1) { if (!hasXml) { xml = DQ.isXml(ci); hasXml = true; } if (!xml) { if (useGetStyle) { a = DQ.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) { value = unescapeCssSelector(value); return DQ.pseudos[name](cs, value); } function nodupIEXml(cs) { var d = ++key, r, i, len, c; cs[0].setAttribute("_nodup", d); r = [ cs[0] ]; for (i = 1 , len = cs.length; i < len; i++) { c = cs[i]; if (!c.getAttribute("_nodup") != d) { c.setAttribute("_nodup", d); r[r.length] = c; } } for (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, d, j; if (!len || typeof cs.nodeType != "undefined" || len == 1) { return cs; } if (isIE && typeof cs[0].selectSingleNode != "undefined") { return nodupIEXml(cs); } d = ++key; cs[0]._nodup = d; for (i = 1; c = cs[i]; i++) { if (c._nodup != d) { c._nodup = d; } else { r = []; for (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 = [], i, len; for (i = 0 , len = c1.length; i < len; i++) { c1[i].setAttribute("_qdiff", d); } for (i = 0 , len = c2.length; i < len; i++) { if (c2[i].getAttribute("_qdiff") != d) { r[r.length] = c2[i]; } } for (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 = [], i, len; if (!len1) { return c2; } if (isIE && typeof c1[0].selectSingleNode != "undefined") { return quickDiffIEXml(c1, c2); } for (i = 0; i < len1; i++) { c1[i]._qdiff = d; } for (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) { id = unescapeCssSelector(id); var d = root.ownerDocument || root; return d.getElementById(id); } ns = getNodes(ns, mode, "*"); return byId(ns, id); } return { singleton: true, alternateClassName: [ 'Ext.core.DomQuery', 'Ext.DomQuery' ], requires: [ 'Ext.dom.Helper', 'Ext.util.Operators' ], _init: function() { DQ = this; DQ.operators = Ext.Object.chain(Ext.util.Operators); DQ._cache = cache = new Ext.util.LruCache({ maxSize: 200 }); DQ._valueCache = valueCache = new Ext.util.LruCache({ maxSize: 200 }); DQ._simpleCache = simpleCache = new Ext.util.LruCache({ maxSize: 200 }); }, clearCache: function() { cache.clear(); valueCache.clear(); simpleCache.clear(); }, getStyle: function(el, name) { return Ext.fly(el, '_DomQuery').getStyle(name); }, compile: function(path, type) { type = type || "select"; var fn = [ "var f = function(root) {\n var mode; ++batch; var n = root || document;\n" ], lastPath, matchers = DQ.matchers, matchersLn = matchers.length, modeMatch, lmode = path.match(modeRe), tokenMatch, matched, j, t, m; path = setupEscapes(path); 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; 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))) { matched = false; for (j = 0; j < matchersLn; j++) { t = matchers[j]; 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 || doc; if (typeof root == "string") { root = doc.getElementById(root); } var paths = Ext.splitAndUnescape(path, ","), results = [], query, i, len, subPath, result; for (i = 0 , len = paths.length; i < len; i++) { subPath = paths[i].replace(trimRe, ""); query = cache.get(subPath); if (!query) { query = DQ.compile(subPath, type); if (!query) { Ext.Error.raise({ sourceClass: 'Ext.DomQuery', sourceMethod: 'jsSelect', msg: subPath + ' is not a valid selector' }); } cache.add(subPath, query); } else { setupEscapes(subPath); } result = query(root); if (result && result !== doc) { 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: doc.querySelectorAll ? function(path, root, type, single) { root = root || doc; if (!DQ.isXml(root)) { try { if (root.parentNode && (root.nodeType !== 9) && path.indexOf(',') === -1 && !startIdRe.test(path)) { path = Ext.makeIdSelector(Ext.id(root)) + ' ' + path; root = root.parentNode; } return single ? [ root.querySelector(path) ] : Ext.Array.toArray(root.querySelectorAll(path)); } catch (e) {} } return DQ.jsSelect.call(this, path, root, type); } : function(path, root, type) { return DQ.jsSelect.call(this, path, root, type); }, selectNode: function(path, root) { return Ext.DomQuery.select(path, root, null, true)[0]; }, selectValue: function(path, root, defaultValue) { path = path.replace(trimRe, ""); var query = valueCache.get(path), n, v; if (!query) { query = DQ.compile(path, "select"); valueCache.add(path, query); } else { setupEscapes(path); } n = query(root); return DQ.getNodeValue(n[0] ? n[0] : n); }, getNodeValue: function(node, defaultValue) { if (typeof node.normalize == 'function') { node.normalize(); } var v = (node && node.firstChild ? node.firstChild.nodeValue : null); return ((v === null || v === undefined || v === '') ? defaultValue : v); }, selectNumber: function(path, root, defaultValue) { var v = DQ.selectValue(path, root, defaultValue || 0); return parseFloat(v); }, is: function(el, ss) { if (typeof el == "string") { el = doc.getElementById(el); } var isArray = Ext.isArray(el), result = DQ.filter(isArray ? el : [ el ], ss); return isArray ? (result.length == el.length) : (result.length > 0); }, filter: function(els, ss, nonMatches) { ss = ss.replace(trimRe, ""); var query = simpleCache.get(ss), result; if (!query) { query = DQ.compile(ss, "simple"); simpleCache.add(ss, query); } else { setupEscapes(ss); } result = query(els); return nonMatches ? quickDiff(result, els) : result; }, matchers: [ { re: /^\.([\w\-\\]+)/, select: useClassList ? 'n = byClassName(n, "{1}");' : '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}")}};' } ], pseudos: { "first-child": function(c) { var r = [], ri = -1, n, i, ci; for (i = 0; (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, i, ci; for (i = 0; (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, i, n, j, cn, pn; for (i = 0; n = c[i]; i++) { pn = n.parentNode; if (batch != pn._batch) { j = 0; for (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, i, ci; for (i = 0; ci = c[i]; i++) { if (!prev(ci) && !next(ci)) { r[++ri] = ci; } } return r; }, "empty": function(c) { var r = [], ri = -1, i, ci, cns, j, cn, empty; for (i = 0; ci = c[i]; i++) { cns = ci.childNodes; j = 0; 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, i, ci; for (i = 0; ci = c[i]; i++) { if ((ci.textContent || ci.innerText || ci.text || '').indexOf(v) != -1) { r[++ri] = ci; } } return r; }, "nodeValue": function(c, v) { var r = [], ri = -1, i, ci; for (i = 0; ci = c[i]; i++) { if (ci.firstChild && ci.firstChild.nodeValue == v) { r[++ri] = ci; } } return r; }, "checked": function(c) { var r = [], ri = -1, i, ci; for (i = 0; ci = c[i]; i++) { if (ci.checked === true) { r[++ri] = ci; } } return r; }, "not": function(c, ss) { return DQ.filter(c, ss, true); }, "any": function(c, selectors) { var ss = selectors.split('|'), r = [], ri = -1, s, i, ci, j; for (i = 0; ci = c[i]; i++) { for (j = 0; s = ss[j]; j++) { if (DQ.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 = DQ.select, r = [], ri = -1, i, ci; for (i = 0; ci = c[i]; i++) { if (s(ss, ci).length > 0) { r[++ri] = ci; } } return r; }, "next": function(c, ss) { var is = DQ.is, r = [], ri = -1, i, ci, n; for (i = 0; ci = c[i]; i++) { n = next(ci); if (n && is(n, ss)) { r[++ri] = ci; } } return r; }, "prev": function(c, ss) { var is = DQ.is, r = [], ri = -1, i, ci, n; for (i = 0; ci = c[i]; i++) { n = prev(ci); if (n && is(n, ss)) { r[++ri] = ci; } } return r; }, focusable: function(candidates) { var len = candidates.length, results = [], i = 0, c; for (; i < len; i++) { c = candidates[i]; if (Ext.fly(c, '_DomQuery').isFocusable()) { results.push(c); } } return results; }, visible: function(candidates, deep) { var len = candidates.length, results = [], i = 0, c; for (; i < len; i++) { c = candidates[i]; if (Ext.fly(c, '_DomQuery').isVisible(deep)) { results.push(c); } } return results; }, isScrolled: function(c) { var r = [], ri = -1, i, ci, s; for (i = 0; ci = c[i]; i++) { s = Ext.fly(ci, '_DomQuery').getScroll(); if (s.top > 0 || s.left > 0) { r[++ri] = ci; } } return r; } } }; }, function() { this._init(); }); Ext.define('Ext.data.reader.Xml', { extend: 'Ext.data.reader.Reader', requires: [ 'Ext.dom.Query' ], alternateClassName: 'Ext.data.XmlReader', alias: 'reader.xml', config: { record: '', namespace: '' }, createAccessor: function(expr) { var me = this; if (Ext.isEmpty(expr)) { return Ext.emptyFn; } if (Ext.isFunction(expr)) { return expr; } return function(root) { return me.getNodeValue(Ext.DomQuery.selectNode(expr, root)); }; }, getNodeValue: function(node) { if (node) { if (typeof node.normalize === 'function') { node.normalize(); } node = node.firstChild; if (node) { return node.nodeValue; } } return undefined; }, getResponseData: function(response) { var xml = response.responseXML, error = 'XML data not found in the response'; if (!xml) { Ext.Logger.warn(error); return this.createReadError(error); } return xml; }, getData: function(data) { return data.documentElement || data; }, getRoot: function(data) { var nodeName = data.nodeName, root = this.getRootProperty(); if (!root || (nodeName && nodeName == root)) { return data; } else if (Ext.DomQuery.isXml(data)) { return Ext.DomQuery.selectNode(root, data); } }, extractData: function(root, readOptions) { var recordName = this.getRecord(); 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, readOptions ]); }, readRecords: function(doc, readOptions, internalReadOptions) { if (Ext.isArray(doc)) { doc = doc[0]; } return this.callParent([ doc, readOptions, internalReadOptions ]); }, createFieldAccessor: function(field) { var me = this, namespace = me.getNamespace(), selector, result; selector = field.mapping || ((namespace ? namespace + '|' : '') + field.name); if (typeof selector === 'function') { result = function(raw) { return field.mapping(raw, me); }; } else { result = function(raw) { return me.getNodeValue(Ext.DomQuery.selectNode(selector, raw)); }; } return result; }, deprecated: { '5.1.1': { properties: { xmlData: null } } } }); Ext.define('Ext.data.writer.Xml', { extend: 'Ext.data.writer.Writer', alternateClassName: 'Ext.data.XmlWriter', alias: 'writer.xml', config: { documentRoot: 'xmlData', defaultDocumentRoot: 'xmlData', header: '', record: 'record' }, selectorRe: /[^>\s]+/g, writeRecords: function(request, data) { var me = this, xml = [], i = 0, len = data.length, root = me.getDocumentRoot(), recordName = me.getRecord(), record = recordName.match(this.selectorRe), recLen = record.length, needsRoot = data.length !== 1 && recLen === 1, transform; transform = this.getTransform(); if (transform) { data = transform(data, request); } xml.push(me.getHeader() || ''); if (!root && needsRoot) { root = me.getDefaultDocumentRoot(); } if (root) { xml.push('<', root, '>'); } for (i = 0; i < recLen - 1; i++) { xml.push('<', record[i], '>'); } recordName = record[i]; for (i = 0; i < len; ++i) { this.objectToElement(recordName, data[i], xml); } for (i = recLen - 2; i > -1; i--) { xml.push(''); } if (root) { xml.push(''); } request.setXmlData(xml.join('')); return request; }, objectToElement: function(name, o, output) { var key, datum, subOutput = [], subKeys, subKeyLen, i, subObject, subObjects, lastObject, lastKey; if (!output) { output = []; } output.push('<', name); for (key in o) { datum = o[key]; if (key[0] === '@') { output.push(' ', key.substr(1), '="', datum, '"'); } else { if (typeof datum === 'object') { this.objectToElement(key, datum, subOutput); } else { subKeys = key.match(this.selectorRe); if ((subKeyLen = subKeys.length) > 1) { subObjects = subObjects || {}; for (subObject = subObjects , i = 0; i < subKeyLen; i++) { lastObject = subObject; lastKey = subKeys[i]; subObject = subObject[lastKey] || (subObject[lastKey] = {}); } lastObject[lastKey] = datum; } else { subOutput.push('<', key, '>', datum, ''); } } } } output.push('>'); output.push.apply(output, subOutput); if (subObjects) { for (key in subObjects) { datum = subObjects[key]; this.objectToElement(key, datum, output); } } output.push(''); return output; } }); Ext.define('Ext.data.XmlStore', { extend: 'Ext.data.Store', alias: 'store.xml', requires: [ 'Ext.data.proxy.Ajax', 'Ext.data.reader.Xml', 'Ext.data.writer.Xml' ], constructor: function(config) { config = Ext.apply({ proxy: { type: 'ajax', reader: 'xml', writer: 'xml' } }, config); this.callParent([ config ]); } }); Ext.define('Ext.data.identifier.Negative', { extend: 'Ext.data.identifier.Sequential', alias: 'data.identifier.negative', config: { increment: -1, seed: -1 } }); Ext.define('Ext.data.identifier.Uuid', { extend: 'Ext.data.identifier.Generator', alias: 'data.identifier.uuid', isUnique: true, config: { id: null }, constructor: function(config) { this.callParent([ config ]); this.reconfigure(config); }, reconfigure: function(config) { var cls = this.self; this.generate = (config && config.version === 1) ? cls.createSequential(config.salt, config.timestamp, config.clockSeq) : cls.createRandom(); }, clone: null, statics: { createRandom: function() { var pattern = 'xxxxxxxx-xxxx-4xxx-Rxxx-xMxxxxxxxxxx'.split(''), hex = '0123456789abcdef'.split(''), length = pattern.length, parts = []; return function() { for (var r, c, i = 0; i < length; ++i) { c = pattern[i]; if (c !== '-' && c !== '4') { r = Math.random() * 16; r = (c === 'R') ? (r & 3 | 8) : (r | ((c === 'M') ? 1 : 0)); c = hex[r]; } parts[i] = c; } return parts.join(''); }; }, createSequential: function(salt, time, clockSeq) { var parts = [], twoPow32 = Math.pow(2, 32), saltLo = salt.lo, saltHi = salt.hi, timeLo = time.lo, timeHi = time.hi, toHex = function(value, length) { var ret = value.toString(16).toLowerCase(); if (ret.length > length) { ret = ret.substring(ret.length - length); } else if (ret.length < length) { ret = Ext.String.leftPad(ret, length, '0'); } return ret; }; if (typeof salt === 'number') { saltHi = Math.floor(salt / twoPow32); saltLo = Math.floor(salt - saltHi * twoPow32); } if (typeof time === 'number') { timeHi = Math.floor(time / twoPow32); timeLo = Math.floor(time - timeHi * twoPow32); } saltHi |= 256; parts[3] = toHex(128 | ((clockSeq >>> 8) & 63), 2) + toHex(clockSeq & 255, 2); parts[4] = toHex(saltHi, 4) + toHex(saltLo, 8); return function() { parts[0] = toHex(timeLo, 8); parts[1] = toHex(timeHi & 65535, 4); parts[2] = toHex(((timeHi >>> 16) & 4095) | (1 << 12), 4); ++timeLo; if (timeLo >= twoPow32) { timeLo = 0; ++timeHi; } return parts.join('-'); }; } } }, function() { this.Global = new this({ id: 'uuid' }); }); Ext.define('Ext.data.proxy.WebStorage', { extend: 'Ext.data.proxy.Client', alternateClassName: 'Ext.data.WebStorageProxy', requires: [ 'Ext.data.identifier.Sequential' ], config: { id: undefined }, constructor: function(config) { this.callParent(arguments); this.cache = {}; if (this.getStorageObject() === undefined) { Ext.Error.raise("Local Storage is not supported in this browser, please use another type of data proxy"); } if (this.getId() === undefined) { Ext.Error.raise("No unique id was provided to the local storage proxy. See Ext.data.proxy.LocalStorage documentation for details"); } this.initialize(); }, create: function(operation) { var me = this, records = operation.getRecords(), length = records.length, ids = me.getIds(), id, record, i, identifier; if (me.isHierarchical === undefined) { me.isHierarchical = !!records[0].isNode; if (me.isHierarchical) { me.getStorageObject().setItem(me.getTreeKey(), true); } } for (i = 0; i < length; i++) { record = records[i]; if (record.phantom) { record.phantom = false; identifier = record.identifier; if (identifier && identifier.isUnique) { id = record.getId(); } else { id = me.getNextId(); } } else { id = record.getId(); } me.setRecord(record, id); record.commit(); ids.push(id); } me.setIds(ids); operation.setSuccessful(true); }, read: function(operation) { var me = this, allRecords, records = [], success = true, Model = me.getModel(), validCount = 0, recordCreator = operation.getRecordCreator(), filters, sorters, limit, filterLen, valid, record, ids, length, data, id, i, j; if (me.isHierarchical) { records = me.getTreeData(); } else { ids = me.getIds(); length = ids.length; id = operation.getId(); if (id) { data = me.getRecord(id); if (data !== null) { record = recordCreator ? recordCreator(data, Model) : new Model(data); } if (record) { records.push(record); } else { success = false; } } else { sorters = operation.getSorters(); filters = operation.getFilters(); limit = operation.getLimit(); allRecords = []; for (i = 0; i < length; i++) { data = me.getRecord(ids[i]); record = recordCreator ? recordCreator(data, Model) : new Model(data); allRecords.push(record); } if (sorters) { Ext.Array.sort(allRecords, Ext.util.Sorter.createComparator(sorters)); } for (i = operation.getStart() || 0; i < length; i++) { record = allRecords[i]; valid = true; if (filters) { for (j = 0 , filterLen = filters.length; j < filterLen; j++) { valid = filters[j].filter(record); } } if (valid) { records.push(record); validCount++; } if (limit && validCount === limit) { break; } } } } if (success) { operation.setResultSet(new Ext.data.ResultSet({ records: records, total: records.length, loaded: true })); operation.setSuccessful(true); } else { operation.setException('Unable to load records'); } }, update: function(operation) { var records = operation.getRecords(), length = records.length, ids = this.getIds(), record, id, i; for (i = 0; i < length; i++) { record = records[i]; this.setRecord(record); record.commit(); id = record.getId(); if (id !== undefined && Ext.Array.indexOf(ids, id) === -1) { ids.push(id); } } this.setIds(ids); operation.setSuccessful(true); }, erase: function(operation) { var me = this, records = operation.getRecords(), ids = me.getIds(), idLength = ids.length, newIds = [], removedHash = {}, i = records.length, id; for (; i--; ) { Ext.apply(removedHash, me.removeRecord(records[i])); } for (i = 0; i < idLength; i++) { id = ids[i]; if (!removedHash[id]) { newIds.push(id); } } me.setIds(newIds); operation.setSuccessful(true); }, getRecord: function(id) { var me = this, cache = me.cache, data = !cache[id] ? Ext.decode(me.getStorageObject().getItem(me.getRecordKey(id))) : cache[id]; if (!data) { return null; } cache[id] = data; data[me.getModel().prototype.idProperty] = id; return Ext.merge({}, data); }, setRecord: function(record, id) { if (id) { record.set('id', id, { commit: true }); } else { id = record.getId(); } var me = this, rawData = record.getData(), data = {}, model = me.getModel(), fields = model.getFields(), length = fields.length, i = 0, field, name, obj, key; for (; i < length; i++) { field = fields[i]; name = field.name; if (field.persist) { data[name] = rawData[name]; } } delete data[model.prototype.idProperty]; if (record.isNode && record.get('depth') === 1) { delete data.parentId; } obj = me.getStorageObject(); key = me.getRecordKey(id); me.cache[id] = data; obj.removeItem(key); obj.setItem(key, Ext.encode(data)); }, removeRecord: function(record) { var me = this, id = record.getId(), records = {}, i, childNodes; records[id] = record; me.getStorageObject().removeItem(me.getRecordKey(id)); delete me.cache[id]; if (record.childNodes) { childNodes = record.childNodes; for (i = childNodes.length; i--; ) { Ext.apply(records, me.removeRecord(childNodes[i])); } } return records; }, getRecordKey: function(id) { if (id.isModel) { id = id.getId(); } return Ext.String.format("{0}-{1}", this.getId(), id); }, getRecordCounterKey: function() { return Ext.String.format("{0}-counter", this.getId()); }, getTreeKey: function() { return Ext.String.format("{0}-tree", this.getId()); }, getIds: function() { var me = this, ids = (me.getStorageObject().getItem(me.getId()) || "").split(","), length = ids.length, isString = this.getIdField().isStringField, i; if (length === 1 && ids[0] === "") { ids = []; } else { for (i = 0; i < length; i++) { ids[i] = isString ? ids[i] : +ids[i]; } } return ids; }, getIdField: function() { return this.getModel().prototype.idField; }, setIds: function(ids) { var obj = this.getStorageObject(), str = ids.join(","), id = this.getId(); obj.removeItem(id); if (!Ext.isEmpty(str)) { obj.setItem(id, str); } }, getNextId: function() { var me = this, obj = me.getStorageObject(), key = me.getRecordCounterKey(), isString = me.getIdField().isStringField, id; id = me.idGenerator.generate(); obj.setItem(key, id); if (isString) { id = id + ''; } return id; }, getTreeData: function() { var me = this, ids = me.getIds(), length = ids.length, records = [], recordHash = {}, root = [], i = 0, Model = me.getModel(), idProperty = Model.prototype.idProperty, rootLength, record, parent, parentId, children, id; for (; i < length; i++) { id = ids[i]; record = me.getRecord(id); records.push(record); recordHash[id] = record; if (!record.parentId) { root.push(record); } } rootLength = root.length; Ext.Array.sort(records, me.sortByParentId); for (i = rootLength; i < length; i++) { record = records[i]; parentId = record.parentId; if (!parent || parent[idProperty] !== parentId) { parent = recordHash[parentId]; parent.children = children = []; } children.push(record); } for (i = length; i--; ) { record = records[i]; if (!record.children && !record.leaf) { record.loaded = true; } } for (i = rootLength; i--; ) { record = root[i]; root[i] = new Model(record); } return root; }, sortByParentId: function(node1, node2) { return (node1.parentId || 0) - (node2.parentId || 0); }, initialize: function() { var me = this, storageObject = me.getStorageObject(), lastId = +storageObject.getItem(me.getRecordCounterKey()), id = me.getId(); storageObject.setItem(id, storageObject.getItem(id) || ""); if (storageObject.getItem(me.getTreeKey())) { me.isHierarchical = true; } me.idGenerator = new Ext.data.identifier.Sequential({ seed: lastId ? lastId + 1 : 1 }); }, clear: function() { var me = this, obj = me.getStorageObject(), ids = me.getIds(), len = ids.length, i; for (i = 0; i < len; i++) { obj.removeItem(me.getRecordKey(ids[i])); } obj.removeItem(me.getRecordCounterKey()); obj.removeItem(me.getTreeKey()); obj.removeItem(me.getId()); me.cache = {}; }, 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.Rest', { extend: 'Ext.data.proxy.Ajax', alternateClassName: 'Ext.data.RestProxy', alias: 'proxy.rest', defaultActionMethods: { create: 'POST', read: 'GET', update: 'PUT', destroy: 'DELETE' }, slashRe: /\/$/, periodRe: /\.$/, config: { appendId: true, format: null, batchActions: false, actionMethods: { create: 'POST', read: 'GET', update: 'PUT', destroy: 'DELETE' } }, buildUrl: function(request) { var me = this, operation = request.getOperation(), records = operation.getRecords(), record = records ? records[0] : null, format = me.getFormat(), url = me.getUrl(request), id, params; if (record && !record.phantom) { id = record.getId(); } else { id = operation.getId(); } if (me.getAppendId() && me.isValidId(id)) { if (!url.match(me.slashRe)) { url += '/'; } url += encodeURIComponent(id); params = request.getParams(); if (params) { delete params[me.getIdParam()]; } } if (format) { if (!url.match(me.periodRe)) { url += '.'; } url += format; } request.setUrl(url); return me.callParent([ request ]); }, isValidId: function(id) { return id || id === 0; } }); Ext.define('Ext.data.proxy.SessionStorage', { extend: 'Ext.data.proxy.WebStorage', alias: 'proxy.sessionstorage', alternateClassName: 'Ext.data.SessionStorageProxy', getStorageObject: function() { return window.sessionStorage; } }); Ext.define('Ext.data.validator.Bound', { extend: 'Ext.data.validator.Validator', alias: 'data.validator.bound', type: 'bound', config: { min: undefined, max: undefined, emptyMessage: 'Must be present', minOnlyMessage: null, maxOnlyMessage: null, bothOnlyMessage: null }, constructor: function() { var me = this; me.preventConfigure = true; me.callParent(arguments); delete me.preventConfigure; me.configure(); }, setConfig: function() { var me = this; me.preventConfigure = true; me.callParent(arguments); delete me.preventConfigure; me.configure(); }, configure: function() { var me = this, hasMin, hasMax, min, max; if (me.preventConfigure) { return; } min = me.getMin(); max = me.getMax(); hasMin = me.hasMin = min !== undefined; hasMax = me.hasMax = max !== undefined; if (hasMin && hasMax) { me._bothMsg = Ext.String.format(me.getBothMessage(), min, max); } else if (hasMin) { me._minMsg = Ext.String.format(me.getMinOnlyMessage(), min); } else if (hasMax) { me._maxMsg = Ext.String.format(me.getMaxOnlyMessage(), max); } }, updateMin: function() { this.configure(); }, updateMax: function() { this.configure(); }, updateMinOnlyMessage: function(v) { this.configure(); }, updateMaxOnlyMessage: function() { this.configure(); }, updateBothMessage: function() { this.configure(); }, validate: function(value) { var me = this, hasMin = me.hasMin, hasMax = me.hasMax, min = me.getMin(), max = me.getMax(), msg = this.validateValue(value), len; if (msg !== true) { return msg; } value = me.getValue(value); if (hasMin && hasMax) { if (value < min || value > max) { msg = me._bothMsg; } } else if (hasMin) { if (value < min) { msg = me._minMsg; } } else if (hasMax) { if (value > max) { msg = me._maxMsg; } } return msg; }, validateValue: function(value) { if (value === undefined || value === null) { return this.getEmptyMessage(); } return true; }, getValue: Ext.identityFn }); Ext.define('Ext.data.validator.Format', { extend: 'Ext.data.validator.Validator', alias: 'data.validator.format', type: 'format', config: { message: 'Is in the wrong format', matcher: undefined }, constructor: function() { this.callParent(arguments); if (!this.getMatcher()) { Ext.Error.raise('validator.Format must be configured with a matcher'); } }, validate: function(value) { var matcher = this.getMatcher(), result = matcher && matcher.test(value); return result ? result : this.getMessage(); } }); Ext.define('Ext.data.validator.Email', { extend: 'Ext.data.validator.Format', alias: 'data.validator.email', type: 'email', config: { message: 'Is not a valid email address', matcher: /^(")?(?:[^\."])(?:(?:[\.])?(?:[\w\-!#$%&'*+\/=?\^_`{|}~]))*\1@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/ } }); Ext.define('Ext.data.validator.List', { extend: 'Ext.data.validator.Validator', alias: 'data.validator.list', type: 'list', config: { list: null }, inclusion: null, validate: function(value) { var contains = Ext.Array.contains(this.getList(), value), inclusion = this.inclusion, exclusion = !inclusion, result; result = (inclusion && contains) || (exclusion && !contains); return result || this.getMessage(); } }); Ext.define('Ext.data.validator.Exclusion', { extend: 'Ext.data.validator.List', alias: 'data.validator.exclusion', type: 'exclusion', config: { message: 'Is a value that has been excluded' }, constructor: function() { this.callParent(arguments); if (!this.getList()) { Ext.Error.raise('validator.Exclusion requires a list'); } }, inclusion: false }); Ext.define('Ext.data.validator.Inclusion', { extend: 'Ext.data.validator.List', alias: 'data.validator.inclusion', type: 'inclusion', config: { message: 'Is not in the list of acceptable values' }, constructor: function() { this.callParent(arguments); if (!this.getList()) { Ext.Error.raise('validator.Inclusion requires a list'); } }, inclusion: true }); Ext.define('Ext.data.validator.Length', { extend: 'Ext.data.validator.Bound', alias: 'data.validator.length', type: 'length', config: { minOnlyMessage: 'Length must be at least {0}', maxOnlyMessage: 'Length must be no more than {0}', bothMessage: 'Length must be between {0} and {1}' }, getValue: function(v) { return String(v).length; } }); Ext.define('Ext.data.validator.Presence', { extend: 'Ext.data.validator.Validator', alias: 'data.validator.presence', type: 'presence', config: { message: 'Must be present', allowEmpty: false }, validate: function(value) { var valid = !(value === undefined || value === null); if (valid && !this.getAllowEmpty()) { valid = !(value === ''); } return valid ? true : this.getMessage(); } }); Ext.define('Ext.data.validator.Range', { extend: 'Ext.data.validator.Bound', alias: 'data.validator.range', type: 'range', config: { minOnlyMessage: 'Must be must be at least {0}', maxOnlyMessage: 'Must be no more than than {0}', bothMessage: 'Must be between {0} and {1}', nanMessage: 'Must be numeric' }, validateValue: function(value) { var msg = this.callParent([ value ]); if (msg === true && isNaN(value)) { msg = this.getNanMessage(); } return msg; } }); Ext.define('Ext.direct.Event', { alias: 'direct.event', status: true, constructor: function(config) { Ext.apply(this, config); }, getName: function() { return this.name; }, getData: function() { return this.data; } }); Ext.define('Ext.direct.RemotingEvent', { extend: 'Ext.direct.Event', alias: 'direct.rpc', getTransaction: function() { var me = this; return me.transaction || Ext.direct.Manager.getTransaction(me.tid); } }); Ext.define('Ext.direct.ExceptionEvent', { extend: 'Ext.direct.RemotingEvent', alias: 'direct.exception', status: false }); Ext.define('Ext.direct.JsonProvider', { extend: 'Ext.direct.Provider', alias: 'direct.jsonprovider', uses: [ 'Ext.direct.ExceptionEvent', 'Ext.direct.Manager' ], parseResponse: function(response) { var text = response && response.responseText; if (text) { if (Ext.isObject(text) || Ext.isArray(text)) { return text; } return Ext.decode(text); } return null; }, createEvents: function(response) { var me = this, data = null, events = [], event, i, len; try { data = me.parseResponse(response); } catch (e) { event = new Ext.direct.ExceptionEvent({ data: e, xhr: response, code: Ext.direct.Manager.exceptions.PARSE, message: 'Error parsing json response: \n\n ' + e }); return [ event ]; } if (Ext.isArray(data)) { for (i = 0 , len = data.length; i < len; ++i) { events.push(me.createEvent(data[i])); } } else if (Ext.isObject(data)) { events.push(me.createEvent(data)); } return events; }, createEvent: function(response) { if (typeof response !== 'object' || !('type' in response)) { return new Ext.direct.ExceptionEvent({ data: response, code: Ext.direct.Manager.exceptions.DATA, message: 'Invalid data: event type is not specified' }); } return Ext.create('direct.' + response.type, response); } }); Ext.define('Ext.direct.PollingProvider', { extend: 'Ext.direct.JsonProvider', alias: 'direct.pollingprovider', requires: [ 'Ext.Ajax', 'Ext.util.TaskRunner', 'Ext.direct.ExceptionEvent' ], type: 'polling', interval: 3000, constructor: function(config) { var me = this; me.callParent([ config ]); me.pollTask = Ext.TaskManager.newTask({ run: me.runPoll, interval: me.interval, scope: me }); }, destroy: function() { this.pollTask = null; this.callParent(); }, doConnect: function() { var me = this, url = me.url, pollFn = me.pollFn; if (pollFn && Ext.isString(pollFn)) { var fnName = pollFn; me.pollFn = pollFn = Ext.direct.Manager.parseMethod(pollFn); if (!Ext.isFunction(pollFn)) { Ext.Error.raise("Cannot resolve Ext.Direct API method " + fnName + " for PollingProvider"); } } else if (Ext.isFunction(url)) { Ext.log.warn('Using a function for url is deprecated, use pollFn instead.'); me.pollFn = pollFn = url; me.url = url = null; } if (url || pollFn) { me.setInterval(me.interval); me.pollTask.start(); } }, doDisconnect: function() { this.pollTask.stop(); }, getInterval: function() { return this.pollTask.interval; }, setInterval: function(interval) { var me = this, pollTask = me.pollTask; if (interval < 100) { Ext.Error.raise("Attempting to configure PollProvider " + me.id + " with interval that is less than 100ms."); } me.interval = pollTask.interval = interval; if (me.isConnected()) { pollTask.restart(interval); } }, runPoll: function() { var me = this, url = me.url, pollFn = me.pollFn, baseParams = me.baseParams, args; if (me.fireEvent('beforepoll', me) !== false) { if (pollFn) { args = pollFn.directCfg.method.getArgs({ params: baseParams !== undefined ? baseParams : {}, callback: me.onPollFn, scope: me }); pollFn.apply(window, args); } else { Ext.Ajax.request({ url: url, callback: me.onData, scope: me, params: baseParams }); } me.fireEvent('poll', me); } }, onData: function(opt, success, response) { var me = this, i, len, events; if (success) { events = me.createEvents(response); for (i = 0 , len = events.length; i < len; ++i) { me.fireEvent('data', me, events[i]); } } else { events = new Ext.direct.ExceptionEvent({ data: null, code: Ext.direct.Manager.exceptions.TRANSPORT, message: 'Unable to connect to the server.', xhr: response }); me.fireEvent('data', me, events); } }, onPollFn: function(result, event, success, options) { this.onData(null, success, { responseText: result }); }, inheritableStatics: { checkConfig: function(config) { return config && config.type === 'polling' && (config.url || config.pollFn); } } }); Ext.define('Ext.direct.RemotingMethod', { constructor: function(config) { var me = this, params = config.params, len = config.len, metadataCfg = config.metadata, metadata = {}, name, pLen, p, param; me.name = config.name; if (config.formHandler) { me.formHandler = config.formHandler; } else if (Ext.isNumeric(len)) { me.len = len; me.ordered = true; } else { me.named = true; me.strict = config.strict !== undefined ? config.strict : true; me.params = {}; pLen = params && params.length; for (p = 0; p < pLen; p++) { param = params[p]; name = Ext.isObject(param) ? param.name : param; me.params[name] = true; } } if (metadataCfg) { params = metadataCfg.params; len = metadataCfg.len; if (Ext.isNumeric(len)) { if (len === 0) { Ext.Error.raise('metadata.len cannot be 0 ' + 'for Ext.Direct method ' + me.name); } metadata.ordered = true; metadata.len = len; } else if (Ext.isArray(params)) { metadata.named = true; metadata.params = {}; for (p = 0 , pLen = params.length; p < pLen; p++) { param = params[p]; metadata.params[param] = true; } metadata.strict = metadataCfg.strict !== undefined ? metadataCfg.strict : true; } else { Ext.Error.raise('metadata is neither named nor ordered ' + 'for Ext.Direct method ' + me.name); } me.metadata = metadata; } }, getArgs: function(config) { var me = this, params = config.params, paramOrder = config.paramOrder, paramsAsHash = config.paramsAsHash, metadata = config.metadata, options = config.options, args = [], i, len; if (me.ordered) { if (me.len > 0) { if (paramOrder) { for (i = 0 , len = paramOrder.length; i < len; i++) { args.push(params[paramOrder[i]]); } } else if (paramsAsHash) { args.push(params); } } } else { args.push(params); } args.push(config.callback, config.scope || window); if (options || metadata) { options = Ext.apply({}, options); if (metadata) { options.metadata = metadata; } args.push(options); } return args; }, getCallData: function(args) { var me = this, data = null, len = me.len, params = me.params, strict = me.strict, form, callback, scope, name, options, metadata; if (me.ordered) { callback = args[len]; scope = args[len + 1]; options = args[len + 2]; if (len !== 0) { data = args.slice(0, len); } } else if (me.formHandler) { form = args[0]; callback = args[1]; scope = args[2]; options = args[3]; } else { data = Ext.apply({}, args[0]); callback = args[1]; scope = args[2]; options = args[3]; if (strict) { for (name in data) { if (data.hasOwnProperty(name) && !params[name]) { delete data[name]; } } } } if (me.metadata && options && options.metadata) { if (me.metadata.ordered) { if (!Ext.isArray(options.metadata)) { Ext.Error.raise('options.metadata is not an Array ' + 'for Ext.Direct method ' + me.name); } else if (options.metadata.length < me.metadata.len) { Ext.Error.raise('Not enough parameters in options.metadata ' + 'for Ext.Direct method ' + me.name); } metadata = options.metadata.slice(0, me.metadata.len); } else { if (!Ext.isObject(options.metadata)) { Ext.Error.raise('options.metadata is not an Object ' + 'for Ext.Direct method ' + me.name); } metadata = Ext.apply({}, options.metadata); if (me.metadata.strict) { for (name in metadata) { if (metadata.hasOwnProperty(name) && !me.metadata.params[name]) { delete metadata[name]; } } } for (name in me.metadata.params) { if (!metadata.hasOwnProperty(name)) { Ext.Error.raise('Named parameter ' + name + ' is missing ' + 'in options.metadata for Ext.Direct method ' + me.name); } } } delete options.metadata; } return { form: form, data: data, metadata: metadata, callback: callback, scope: scope, options: options }; } }); Ext.define('Ext.direct.Transaction', { alias: 'direct.transaction', alternateClassName: 'Ext.Direct.Transaction', statics: { TRANSACTION_ID: 0 }, constructor: function(config) { var me = this; Ext.apply(me, config); me.id = me.tid = ++me.self.TRANSACTION_ID; me.retryCount = 0; }, send: function() { var me = this; me.provider.queueTransaction(me); }, retry: function() { var me = this; me.retryCount++; me.send(); }, getProvider: function() { return this.provider; } }); Ext.define('Ext.direct.RemotingProvider', { extend: 'Ext.direct.JsonProvider', alias: 'direct.remotingprovider', requires: [ 'Ext.util.MixedCollection', 'Ext.util.DelayedTask', 'Ext.direct.Transaction', 'Ext.direct.RemotingMethod', 'Ext.direct.Manager' ], type: 'remoting', enableBuffer: 10, maxRetries: 1, constructor: function(config) { var me = this; me.callParent(arguments); me.namespace = (Ext.isString(me.namespace)) ? Ext.ns(me.namespace) : me.namespace || Ext.global; me.transactions = new Ext.util.MixedCollection(); me.callBuffer = []; }, doConnect: function() { if (!this.apiCreated) { this.initAPI(); this.apiCreated = true; } }, getNamespace: function(root, action) { var parts, ns, i, len; root = root || Ext.global; parts = action.toString().split('.'); for (i = 0 , len = parts.length; i < len; i++) { ns = parts[i]; root = root[ns]; if (typeof root === 'undefined') { return root; } } return root; }, createNamespaces: function(root, action) { var parts, ns, i, len; root = root || Ext.global; parts = action.toString().split('.'); for (i = 0 , len = parts.length; i < len; i++) { ns = parts[i]; root[ns] = root[ns] || {}; root = root[ns]; } return root; }, initAPI: function() { var me = this, actions = me.actions, namespace = me.namespace, Manager = Ext.direct.Manager, action, cls, methods, i, len, method, handler; for (action in actions) { if (actions.hasOwnProperty(action)) { if (me.disableNestedActions) { cls = namespace[action]; if (!cls) { cls = namespace[action] = {}; } } else { cls = me.getNamespace(namespace, action); if (!cls) { cls = me.createNamespaces(namespace, action); } } methods = actions[action]; for (i = 0 , len = methods.length; i < len; ++i) { method = new Ext.direct.RemotingMethod(methods[i]); cls[method.name] = handler = me.createHandler(action, method); Manager.registerMethod(handler.$name, handler); } } } }, createHandler: function(action, method) { var me = this, slice = Array.prototype.slice, handler; if (!method.formHandler) { handler = function() { me.configureRequest(action, method, slice.call(arguments, 0)); }; } else { handler = function() { me.configureFormRequest(action, method, slice.call(arguments, 0)); }; } handler.name = handler.$name = action + '.' + method.name; handler.$directFn = true; handler.directCfg = handler.$directCfg = { action: action, method: method }; return handler; }, connect: function() { var me = this; if (!me.url) { Ext.Error.raise('Error initializing RemotingProvider "' + me.id + '", no url configured.'); } me.callParent(); }, runCallback: function(transaction, event) { var success = !!event.status, funcName = success ? 'success' : 'failure', callback, options, result; if (transaction && transaction.callback) { callback = transaction.callback; options = transaction.callbackOptions; result = typeof event.result !== 'undefined' ? event.result : event.data; if (Ext.isFunction(callback)) { callback(result, event, success, options); } else { Ext.callback(callback[funcName], callback.scope, [ result, event, success, options ]); Ext.callback(callback.callback, callback.scope, [ result, event, success, options ]); } } }, onData: function(options, success, response) { var me = this, i, len, events, event, transaction, transactions; if (success) { events = me.createEvents(response); for (i = 0 , len = events.length; i < len; ++i) { event = events[i]; transaction = me.getTransaction(event); me.fireEvent('data', me, event); if (transaction && me.fireEvent('beforecallback', me, event, transaction) !== false) { me.runCallback(transaction, event, true); Ext.direct.Manager.removeTransaction(transaction); } } } else { transactions = [].concat(options.transaction); for (i = 0 , len = transactions.length; i < len; ++i) { transaction = me.getTransaction(transactions[i]); if (transaction && transaction.retryCount < me.maxRetries) { transaction.retry(); } else { event = new Ext.direct.ExceptionEvent({ data: null, transaction: transaction, code: Ext.direct.Manager.exceptions.TRANSPORT, message: 'Unable to connect to the server.', xhr: response }); me.fireEvent('data', me, event); if (transaction && me.fireEvent('beforecallback', me, transaction) !== false) { me.runCallback(transaction, event, false); Ext.direct.Manager.removeTransaction(transaction); } } } } }, getTransaction: function(options) { return options && options.tid ? Ext.direct.Manager.getTransaction(options.tid) : null; }, getPayload: function(transaction) { var result = { action: transaction.action, method: transaction.method, data: transaction.data, type: 'rpc', tid: transaction.id }; if (transaction.metadata) { result.metadata = transaction.metadata; } return result; }, sendRequest: function(transaction) { var me = this, request, callData, params, enableUrlEncode = me.enableUrlEncode, payload, i, len; request = { url: me.url, callback: me.onData, scope: me, transaction: transaction, timeout: me.timeout }; if (transaction.timeout) { request.timeout = transaction.timeout; } if (Ext.isArray(transaction)) { callData = []; for (i = 0 , len = transaction.length; i < len; ++i) { payload = me.getPayload(transaction[i]); callData.push(payload); } } else { callData = me.getPayload(transaction); } 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; } if (enableBuffer === false || typeof transaction.timeout !== 'undefined') { me.sendRequest(transaction); return; } me.callBuffer.push(transaction); if (enableBuffer) { if (!me.callTask) { me.callTask = new Ext.util.DelayedTask(me.combineAndSend, me); } me.callTask.delay(Ext.isNumber(enableBuffer) ? enableBuffer : 10); } else { me.combineAndSend(); } }, combineAndSend: function() { var me = this, buffer = me.callBuffer, len = buffer.length; if (len > 0) { me.sendRequest(len === 1 ? buffer[0] : buffer); me.callBuffer = []; } }, configureTransaction: function(action, method, args, isForm) { var data, cb, scope, options, params; data = method.getCallData(args); cb = data.callback; scope = data.scope; options = data.options; if (cb && !Ext.isFunction(cb)) { Ext.Error.raise("Callback argument is not a function " + "for Ext.Direct method " + action + "." + method.name); } cb = cb && scope ? Ext.Function.bind(cb, scope) : cb; params = Ext.apply({}, { provider: this, args: args, action: action, method: method.name, form: data.form, data: data.data, metadata: data.metadata, callbackOptions: options, callback: cb, isForm: isForm }); if (options && options.timeout != null) { params.timeout = options.timeout; } return new Ext.direct.Transaction(params); }, configureRequest: function(action, method, args) { var me = this, transaction; transaction = me.configureTransaction(action, method, args); if (me.fireEvent('beforecall', me, transaction, method) !== false) { Ext.direct.Manager.addTransaction(transaction); me.queueTransaction(transaction); me.fireEvent('call', me, transaction, method); } }, configureFormRequest: function(action, method, args) { var me = this, transaction, form, isUpload, postParams; transaction = me.configureTransaction(action, method, args, true); if (me.fireEvent('beforecall', me, transaction, method) !== false) { Ext.direct.Manager.addTransaction(transaction); form = transaction.form; isUpload = String(form.getAttribute("enctype")).toLowerCase() === 'multipart/form-data'; postParams = { extTID: transaction.id, extAction: action, extMethod: method.name, extType: 'rpc', extUpload: String(isUpload) }; if (transaction.metadata) { postParams.extMetadata = Ext.JSON.encode(transaction.metadata); } Ext.apply(transaction, { form: form, isUpload: isUpload, params: postParams }); me.sendFormRequest(transaction); me.fireEvent('call', me, transaction, method); } }, sendFormRequest: function(transaction) { var me = this; Ext.Ajax.request({ url: me.url, params: transaction.params, callback: me.onData, scope: me, form: transaction.form, isUpload: transaction.isUpload, transaction: transaction }); }, inheritableStatics: { checkConfig: function(config) { return config && config.type === 'remoting' && config.url && Ext.isArray(config.actions); } } }); Ext.define('Ext.dom.GarbageCollector', { singleton: true, interval: 30000, constructor: function() { var me = this; me.collect = Ext.Function.bind(me.collect, me); me.lastTime = Ext.now(); me.resume(); }, collect: function() { var me = this, cache = Ext.cache, eid, dom, el, t, isGarbage, tagName; var collectedIds = []; for (eid in cache) { if (!cache.hasOwnProperty(eid)) { continue; } el = cache[eid]; if (el.skipGarbageCollection) { continue; } dom = el.dom; if (!dom) { Ext.Error.raise('Missing DOM node in element garbage collection: ' + eid); } try { isGarbage = Ext.isGarbage(dom); } catch (e) { delete cache[eid]; collectedIds.push('#' + el.id); continue; } if (isGarbage) { if (el && el.dom) { tagName = el.dom.tagName; el.collect(); collectedIds.push((tagName ? tagName : '') + '#' + el.id); } } } if (Ext.isIE9m) { t = {}; for (eid in cache) { if (cache.hasOwnProperty(eid)) { t[eid] = cache[eid]; } } Ext.cache = Ext.dom.Element.cache = t; } me.lastTime = Ext.now(); return collectedIds; }, pause: function() { clearTimeout(this.timerId); }, resume: function() { var me = this, lastTime = me.lastTime; if (Ext.enableGarbageCollector && (Ext.now() - lastTime > me.interval)) { me.collect(); } me.timerId = Ext.interval(me.collect, me.interval); } }); Ext.define('Ext.event.gesture.Recognizer', { requires: [ 'Ext.event.publisher.Gesture' ], mixins: [ 'Ext.mixin.Identifiable' ], priority: 0, handledEvents: [], config: { onRecognized: Ext.emptyFn, callbackScope: null }, constructor: function(config) { this.initConfig(config); Ext.event.publisher.Gesture.instance.registerRecognizer(this); }, onStart: Ext.emptyFn, onEnd: Ext.emptyFn, onTouchStart: Ext.emptyFn, onTouchMove: Ext.emptyFn, onTouchEnd: Ext.emptyFn, onTouchCancel: Ext.emptyFn, fail: function() { return false; }, fire: function() { this.getOnRecognized().apply(this.getCallbackScope(), arguments); }, reset: Ext.emptyFn, debugHooks: { $enabled: false, fail: function(msg) { Ext.log.info(this.$className + ' Gesture Failed: ' + msg); return false; } } }); Ext.define('Ext.event.gesture.SingleTouch', { extend: 'Ext.event.gesture.Recognizer', inheritableStatics: { NOT_SINGLE_TOUCH: "Not Single Touch", TOUCH_MOVED: "Touch Moved", EVENT_CANCELED: "Event Canceled" }, onTouchStart: function(e) { if (e.touches.length > 1) { return this.fail(this.self.NOT_SINGLE_TOUCH); } }, onTouchCancel: function() { return false; } }); Ext.define('Ext.event.gesture.DoubleTap', { extend: 'Ext.event.gesture.SingleTouch', priority: 300, inheritableStatics: { DIFFERENT_TARGET: 'Different Target' }, config: { moveDistance: 8, tapDistance: 24, maxDuration: 300 }, handledEvents: [ 'singletap', 'doubletap' ], singleTapTimer: null, startTime: 0, lastTapTime: 0, onTouchStart: function(e) { var me = this, lastStartPoint; if (me.callParent(arguments) === false) { return false; } lastStartPoint = me.lastStartPoint = e.changedTouches[0].point; me.startPoint = me.startPoint || lastStartPoint; me.startTime = e.time; clearTimeout(me.singleTapTimer); }, onTouchMove: function(e) { var me = this, point = e.changedTouches[0].point; if (Math.abs(point.getDistanceTo(me.lastStartPoint)) >= me.getMoveDistance()) { me.startPoint = null; return me.fail(me.self.TOUCH_MOVED); } }, onTouchEnd: function(e) { var me = this, maxDuration = me.getMaxDuration(), time = e.time, target = e.target, lastTapTime = me.lastTapTime, lastTarget = me.lastTarget, point = e.changedTouches[0].point, duration; me.lastTapTime = time; me.lastTarget = target; if (lastTapTime) { duration = time - lastTapTime; if (duration <= maxDuration && Math.abs(point.getDistanceTo(me.startPoint)) <= me.getTapDistance()) { if (target !== lastTarget) { return me.fail(me.self.DIFFERENT_TARGET); } me.lastTarget = null; me.lastTapTime = 0; me.fire('doubletap', e, { touch: e.changedTouches[0], duration: duration }); me.startPoint = null; return; } } if (time - me.startTime > maxDuration) { me.fireSingleTap(e); } else { me.setSingleTapTimer(e); } }, setSingleTapTimer: function(e) { var me = this; me.singleTapTimer = Ext.defer(function() { me.fireSingleTap(e); }, me.getMaxDuration()); }, fireSingleTap: function(e, touch) { this.fire('singletap', e, { touch: touch }); this.startPoint = null; }, reset: function() { var me = this; me.startTime = me.lastTapTime = 0; me.lastStartPoint = me.startPoint = me.singleTapTimer = null; } }, function(DoubleTap) { var gestures = Ext.manifest.gestures; DoubleTap.instance = new DoubleTap(gestures && gestures.doubleTap); }); Ext.define('Ext.event.gesture.Drag', { extend: 'Ext.event.gesture.SingleTouch', priority: 100, isStarted: false, startPoint: null, previousPoint: null, lastPoint: null, handledEvents: [ 'dragstart', 'drag', 'dragend', 'dragcancel' ], config: { minDistance: 8 }, constructor: function() { this.callParent(arguments); this.initInfo(); }, initInfo: function() { this.info = { touch: null, previous: { x: 0, y: 0 }, x: 0, y: 0, delta: { x: 0, y: 0 }, absDelta: { x: 0, y: 0 }, flick: { velocity: { x: 0, y: 0 } }, direction: { x: 0, y: 0 }, time: 0, previousTime: { x: 0, y: 0 } }; }, onTouchStart: function(e) { if (this.callParent(arguments) === false) { if (this.isStarted && this.lastMoveEvent !== null) { this.lastMoveEvent.isStopped = false; this.onTouchEnd(this.lastMoveEvent); } return false; } this.startTime = e.time; this.startPoint = e.changedTouches[0].point; }, tryDragStart: function(e) { var startPoint = this.startPoint, touch = e.changedTouches[0], point = touch.point, minDistance = this.getMinDistance(), info = this.info; if (Math.abs(point.getDistanceTo(startPoint)) >= minDistance) { this.isStarted = true; this.previousPoint = this.lastPoint = point; this.resetInfo('x', e, touch); this.resetInfo('y', e, touch); info.time = e.time; this.fire('dragstart', e, info); } }, onTouchMove: function(e) { if (!this.isStarted) { this.tryDragStart(e); } if (!this.isStarted) { return; } var touch = e.changedTouches[0], point = touch.point; if (this.lastPoint) { this.previousPoint = this.lastPoint; } this.lastPoint = point; this.lastMoveEvent = e; this.updateInfo('x', e, touch); this.updateInfo('y', e, touch); this.info.time = e.time; this.fire('drag', e, this.info); }, onAxisDragEnd: function(axis, info) { var duration = info.time - info.previousTime[axis]; if (duration > 0) { info.flick.velocity[axis] = (info[axis] - info.previous[axis]) / duration; } }, resetInfo: function(axis, e, touch) { var value = this.lastPoint[axis], startValue = this.startPoint[axis], delta = value - startValue, capAxis = axis.toUpperCase(), info = this.info; info.touch = touch; info.delta[axis] = delta; info.absDelta[axis] = Math.abs(delta); info.previousTime[axis] = this.startTime; info.previous[axis] = startValue; info[axis] = value; info.direction[axis] = 0; info['start' + capAxis] = this.startPoint[axis]; info['previous' + capAxis] = info.previous[axis]; info['page' + capAxis] = info[axis]; info['delta' + capAxis] = info.delta[axis]; info['absDelta' + capAxis] = info.absDelta[axis]; info['previousDelta' + capAxis] = 0; info.startTime = this.startTime; }, updateInfo: function(axis, e, touch) { var me = this, value = me.lastPoint[axis], previousValue = me.previousPoint[axis], startValue = me.startPoint[axis], delta = value - startValue, info = me.info, direction = info.direction, capAxis = axis.toUpperCase(), previousFlick = info.previous[axis]; info.touch = touch; info.delta[axis] = delta; info.absDelta[axis] = Math.abs(delta); if (value !== previousFlick && value !== info[axis]) { info.previous[axis] = info[axis]; info.previousTime[axis] = info.time; } info[axis] = value; if (value > previousValue) { direction[axis] = 1; } else if (value < previousValue) { direction[axis] = -1; } info['start' + capAxis] = startValue; info['previous' + capAxis] = info.previous[axis]; info['page' + capAxis] = info[axis]; info['delta' + capAxis] = info.delta[axis]; info['absDelta' + capAxis] = info.absDelta[axis]; info['previousDelta' + capAxis] = info.previous[axis] - startValue; info.startTime = me.startTime; }, onTouchEnd: function(e) { this.doEnd(e); }, onTouchCancel: function(e) { this.doEnd(e, true); return false; }, doEnd: function(e, isCancel) { if (!this.isStarted) { this.tryDragStart(e); } if (this.isStarted) { var touch = e.changedTouches[0], point = touch.point, info = this.info; this.isStarted = false; this.lastPoint = point; this.updateInfo('x', e, touch); this.updateInfo('y', e, touch); info.time = e.time; this.onAxisDragEnd('x', info); this.onAxisDragEnd('y', info); this.fire(isCancel ? 'dragcancel' : 'dragend', e, info); this.startPoint = null; this.previousPoint = null; this.lastPoint = null; this.lastMoveEvent = null; } }, reset: function() { var me = this; me.isStarted = me.lastPoint = me.startPoint = me.previousPoint = me.lastPoint = me.lastMoveEvent = null; me.initInfo(); } }, function(Drag) { var gestures = Ext.manifest.gestures; Drag.instance = new Drag(gestures && gestures.drag); }); Ext.define('Ext.event.gesture.Swipe', { extend: 'Ext.event.gesture.SingleTouch', priority: 500, handledEvents: [ 'swipestart', 'swipe', 'swipecancel' ], inheritableStatics: { MAX_OFFSET_EXCEEDED: 'Max Offset Exceeded', MAX_DURATION_EXCEEDED: 'Max Duration Exceeded', DISTANCE_NOT_ENOUGH: 'Distance Not Enough' }, config: { minDistance: 80, maxOffset: 35, maxDuration: 1000 }, onTouchStart: function(e) { if (this.callParent(arguments) === false) { return false; } var touch = e.changedTouches[0]; this.startTime = e.time; this.isHorizontal = true; this.isVertical = true; this.startX = touch.pageX; this.startY = touch.pageY; }, onTouchMove: function(e) { var touch = e.changedTouches[0], x = touch.pageX, y = touch.pageY, deltaX = x - this.startX, deltaY = y - this.startY, absDeltaX = Math.abs(x - this.startX), absDeltaY = Math.abs(y - this.startY), duration = e.time - this.startTime, minDistance = this.getMinDistance(), time = e.time, direction, distance; if (time - this.startTime > this.getMaxDuration()) { return this.fail(this.self.MAX_DURATION_EXCEEDED); } if (this.isHorizontal && absDeltaY > this.getMaxOffset()) { this.isHorizontal = false; } if (this.isVertical && absDeltaX > this.getMaxOffset()) { this.isVertical = false; } if (!this.isVertical || !this.isHorizontal) { if (this.isHorizontal && absDeltaX < minDistance) { direction = (deltaX < 0) ? 'left' : 'right'; distance = absDeltaX; } else if (this.isVertical && absDeltaY < minDistance) { direction = (deltaY < 0) ? 'up' : 'down'; distance = absDeltaY; } } if (direction && !this.started) { this.started = true; this.fire('swipestart', e, { touch: touch, direction: direction, distance: distance, duration: duration }); } if (!this.isHorizontal && !this.isVertical) { return this.fail(this.self.MAX_OFFSET_EXCEEDED); } }, onTouchEnd: function(e) { if (this.onTouchMove(e) === false) { return false; } var touch = e.changedTouches[0], x = touch.pageX, y = touch.pageY, deltaX = x - this.startX, deltaY = y - this.startY, absDeltaX = Math.abs(deltaX), absDeltaY = Math.abs(deltaY), minDistance = this.getMinDistance(), duration = e.time - this.startTime, direction, distance; if (this.isVertical && absDeltaY < minDistance) { this.isVertical = false; } if (this.isHorizontal && absDeltaX < minDistance) { this.isHorizontal = false; } if (this.isHorizontal) { direction = (deltaX < 0) ? 'left' : 'right'; distance = absDeltaX; } else if (this.isVertical) { direction = (deltaY < 0) ? 'up' : 'down'; distance = absDeltaY; } else { return this.fail(this.self.DISTANCE_NOT_ENOUGH); } this.started = false; this.fire('swipe', e, { touch: touch, direction: direction, distance: distance, duration: duration }); }, onTouchCancel: function(e) { this.fire('swipecancel', e); return false; }, reset: function() { var me = this; me.startTime = me.isHorizontal = me.isVertical = me.startX = me.startY = null; } }, function(Swipe) { var gestures = Ext.manifest.gestures; Swipe.instance = new Swipe(gestures && gestures.swipe); }); Ext.define('Ext.event.gesture.EdgeSwipe', { extend: 'Ext.event.gesture.Swipe', priority: 800, handledEvents: [ 'edgeswipe', 'edgeswipestart', 'edgeswipeend', 'edgeswipecancel' ], inheritableStatics: { NOT_NEAR_EDGE: 'Not Near Edge' }, config: { minDistance: 60 }, onTouchStart: function(e) { if (this.callParent(arguments) === false) { return false; } var touch = e.changedTouches[0]; this.started = false; this.direction = null; this.isHorizontal = true; this.isVertical = true; this.startX = touch.pageX; this.startY = touch.pageY; }, onTouchMove: function(e) { var touch = e.changedTouches[0], x = touch.pageX, y = touch.pageY, deltaX = x - this.startX, deltaY = y - this.startY, absDeltaY = Math.abs(y - this.startY), absDeltaX = Math.abs(x - this.startX), minDistance = this.getMinDistance(), maxOffset = this.getMaxOffset(), duration = e.time - this.startTime, elementWidth = Ext.Viewport && Ext.Element.getViewportWidth(), elementHeight = Ext.Viewport && Ext.Element.getViewportHeight(), direction, distance; if (this.isVertical && absDeltaX > maxOffset) { this.isVertical = false; } if (this.isHorizontal && absDeltaY > maxOffset) { this.isHorizontal = false; } if (this.isVertical && this.isHorizontal) { if (absDeltaY > absDeltaX) { this.isHorizontal = false; } else { this.isVertical = false; } } if (this.isHorizontal) { direction = (deltaX < 0) ? 'left' : 'right'; distance = deltaX; } else if (this.isVertical) { direction = (deltaY < 0) ? 'up' : 'down'; distance = deltaY; } direction = this.direction || (this.direction = direction); if (direction === 'up') { distance = deltaY * -1; } else if (direction === 'left') { distance = deltaX * -1; } this.distance = distance; if (!distance) { return this.fail(this.self.DISTANCE_NOT_ENOUGH); } if (!this.started) { if (direction === 'right' && this.startX > minDistance) { return this.fail(this.self.NOT_NEAR_EDGE); } else if (direction === 'down' && this.startY > minDistance) { return this.fail(this.self.NOT_NEAR_EDGE); } else if (direction === 'left' && (elementWidth - this.startX) > minDistance) { return this.fail(this.self.NOT_NEAR_EDGE); } else if (direction === 'up' && (elementHeight - this.startY) > minDistance) { return this.fail(this.self.NOT_NEAR_EDGE); } this.started = true; this.startTime = e.time; this.fire('edgeswipestart', e, { touch: touch, direction: direction, distance: distance, duration: duration }); } else { this.fire('edgeswipe', e, { touch: touch, direction: direction, distance: distance, duration: duration }); } }, onTouchEnd: function(e) { var duration; if (this.onTouchMove(e) !== false) { duration = e.time - this.startTime; this.fire('edgeswipeend', e, { touch: e.changedTouches[0], direction: this.direction, distance: this.distance, duration: duration }); } }, onTouchCancel: function(e) { this.fire('edgeswipecancel', e, { touch: e.changedTouches[0] }); return false; }, reset: function() { var me = this; me.started = me.direction = me.isHorizontal = me.isVertical = me.startX = me.startY = me.startTime = me.distance = null; } }, function(EdgeSwipe) { var gestures = Ext.manifest.gestures; EdgeSwipe.instance = new EdgeSwipe(gestures && gestures.edgeSwipe); }); Ext.define('Ext.event.gesture.LongPress', { extend: 'Ext.event.gesture.SingleTouch', priority: 400, inheritableStatics: { DURATION_NOT_ENOUGH: 'Duration Not Enough' }, config: { moveDistance: 8, minDuration: 1000 }, handledEvents: [ 'longpress', 'taphold' ], fireLongPress: function(e) { this.fire('longpress', e, { touch: e.changedTouches[0], duration: this.getMinDuration() }); this.isLongPress = true; }, onTouchStart: function(e) { if (this.callParent(arguments) === false) { return false; } this.startPoint = e.changedTouches[0].point; this.isLongPress = false; this.setLongPressTimer(e); }, setLongPressTimer: function(e) { var me = this; me.timer = Ext.defer(function() { me.fireLongPress(e); }, me.getMinDuration()); }, onTouchMove: function(e) { var point = e.changedTouches[0].point; if (Math.abs(point.getDistanceTo(this.startPoint)) >= this.getMoveDistance()) { return this.fail(this.self.TOUCH_MOVED); } }, onTouchEnd: function() { if (!this.isLongPress) { return this.fail(this.self.DURATION_NOT_ENOUGH); } }, fail: function() { clearTimeout(this.timer); return this.callParent(arguments); }, reset: function() { this.isLongPress = this.startPoint = null; }, fire: function(eventName) { if (eventName === 'longpress') { var args = Array.prototype.slice.call(arguments); args[0] = 'taphold'; this.fire.apply(this, args); } return this.callParent(arguments); } }, function(LongPress) { var gestures = Ext.manifest.gestures; LongPress.instance = new LongPress(gestures && gestures.longPress); }); Ext.define('Ext.event.gesture.MultiTouch', { extend: 'Ext.event.gesture.Recognizer', requiredTouchesCount: 2, isTracking: false, isStarted: false, onTouchStart: function(e) { var requiredTouchesCount = this.requiredTouchesCount, touches = e.touches, touchesCount = touches.length; if (touchesCount === requiredTouchesCount) { this.start(e); } else if (touchesCount > requiredTouchesCount) { this.end(e); } }, onTouchEnd: function(e) { this.end(e); }, onTouchCancel: function(e) { this.end(e, true); return false; }, start: function() { if (!this.isTracking) { this.isTracking = true; this.isStarted = false; } }, end: function(e, isCancel) { if (this.isTracking) { this.isTracking = false; if (this.isStarted) { this.isStarted = false; this[isCancel ? 'fireCancel' : 'fireEnd'](e); } } }, reset: function() { this.isTracking = this.isStarted = false; } }); Ext.define('Ext.event.gesture.Pinch', { extend: 'Ext.event.gesture.MultiTouch', priority: 600, handledEvents: [ 'pinchstart', 'pinch', 'pinchend', 'pinchcancel' ], startDistance: 0, lastTouches: null, onTouchMove: function(e) { if (!this.isTracking) { return; } var touches = e.touches, firstPoint, secondPoint, distance; firstPoint = touches[0].point; secondPoint = touches[1].point; distance = firstPoint.getDistanceTo(secondPoint); if (distance === 0) { return; } if (!this.isStarted) { this.isStarted = true; this.startDistance = distance; this.fire('pinchstart', e, { touches: touches, distance: distance, scale: 1 }); } else { this.fire('pinch', e, { touches: touches, distance: distance, scale: distance / this.startDistance }); } }, fireEnd: function(e) { this.fire('pinchend', e); }, fireCancel: function(e) { this.fire('pinchcancel', e); }, fail: function() { return this.callParent(arguments); }, reset: function() { this.lastTouches = null; this.startDistance = 0; this.callParent(); } }, function(Pinch) { var gestures = Ext.manifest.gestures; Pinch.instance = new Pinch(gestures && gestures.pinch); }); Ext.define('Ext.event.gesture.Rotate', { extend: 'Ext.event.gesture.MultiTouch', priority: 700, handledEvents: [ 'rotatestart', 'rotate', 'rotateend', 'rotatecancel' ], startAngle: 0, lastTouches: null, lastAngle: null, onTouchMove: function(e) { if (!this.isTracking) { return; } var touches = e.touches, lastAngle = this.lastAngle, firstPoint, secondPoint, angle, nextAngle, previousAngle, diff; firstPoint = touches[0].point; secondPoint = touches[1].point; angle = firstPoint.getAngleTo(secondPoint); if (lastAngle !== null) { diff = Math.abs(lastAngle - angle); nextAngle = angle + 360; previousAngle = angle - 360; if (Math.abs(nextAngle - lastAngle) < diff) { angle = nextAngle; } else if (Math.abs(previousAngle - lastAngle) < diff) { angle = previousAngle; } } this.lastAngle = angle; if (!this.isStarted) { this.isStarted = true; this.startAngle = angle; this.fire('rotatestart', e, { touches: touches, angle: angle, rotation: 0 }); } else { this.fire('rotate', e, { touches: touches, angle: angle, rotation: angle - this.startAngle }); } this.lastTouches = Ext.Array.clone(touches); }, fireEnd: function(e) { this.lastAngle = null; this.fire('rotateend', e); }, fireCancel: function(e) { this.lastAngle = null; this.fire('rotatecancel', e); }, reset: function() { var me = this; me.lastTouches = me.lastAngle = me.startAngle = null; this.callParent(); } }, function(Rotate) { var gestures = Ext.manifest.gestures; Rotate.instance = new Rotate(gestures && gestures.rotate); }); Ext.define('Ext.event.gesture.Tap', { extend: 'Ext.event.gesture.SingleTouch', priority: 200, handledEvents: [ 'tap', 'tapcancel' ], config: { moveDistance: 8 }, onTouchStart: function(e) { if (this.callParent([ e ]) === false) { return false; } this.startPoint = e.changedTouches[0].point; }, onTouchMove: function(e) { var touch = e.changedTouches[0], point = touch.point; if (Math.abs(point.getDistanceTo(this.startPoint)) >= this.getMoveDistance()) { this.fire('tapcancel', e, { touch: touch }); return this.fail(this.self.TOUCH_MOVED); } }, onTouchEnd: function(e) { this.fire('tap', e, { touch: e.changedTouches[0] }); }, onTouchCancel: function(e) { this.fire('tapcancel', e, { touch: e.changedTouches[0] }); return false; }, reset: function() { this.startPoint = null; } }, function(Tap) { var gestures = Ext.manifest.gestures; Tap.instance = new Tap(gestures && gestures.tap); }); Ext.define('Ext.fx.State', { isAnimatable: { 'background-color': true, 'background-image': true, 'background-position': true, 'border-bottom-color': true, 'border-bottom-width': true, 'border-color': true, 'border-left-color': true, 'border-left-width': true, 'border-right-color': true, 'border-right-width': true, 'border-spacing': true, 'border-top-color': true, 'border-top-width': true, 'border-width': true, 'bottom': true, 'color': true, 'crop': true, 'font-size': true, 'font-weight': true, 'height': true, 'left': true, 'letter-spacing': true, 'line-height': true, 'margin-bottom': true, 'margin-left': true, 'margin-right': true, 'margin-top': true, 'max-height': true, 'max-width': true, 'min-height': true, 'min-width': true, 'opacity': true, 'outline-color': true, 'outline-offset': true, 'outline-width': true, 'padding-bottom': true, 'padding-left': true, 'padding-right': true, 'padding-top': true, 'right': true, 'text-indent': true, 'text-shadow': true, 'top': true, 'vertical-align': true, 'visibility': true, 'width': true, 'word-spacing': true, 'z-index': true, 'zoom': true, 'transform': true }, constructor: function(data) { this.data = {}; this.set(data); }, setConfig: function(data) { this.set(data); return this; }, setRaw: function(data) { this.data = data; return this; }, clear: function() { return this.setRaw({}); }, setTransform: function(name, value) { var data = this.data, isArray = Ext.isArray(value), transform = data.transform, ln, key; if (!transform) { transform = data.transform = { translateX: 0, translateY: 0, translateZ: 0, scaleX: 1, scaleY: 1, scaleZ: 1, rotate: 0, rotateX: 0, rotateY: 0, rotateZ: 0, skewX: 0, skewY: 0 }; } if (typeof name == 'string') { switch (name) { case 'translate': if (isArray) { ln = value.length; if (ln == 0) { break; } transform.translateX = value[0]; if (ln == 1) { break; } transform.translateY = value[1]; if (ln == 2) { break; } transform.translateZ = value[2]; } else { transform.translateX = value; }; break; case 'rotate': if (isArray) { ln = value.length; if (ln == 0) { break; } transform.rotateX = value[0]; if (ln == 1) { break; } transform.rotateY = value[1]; if (ln == 2) { break; } transform.rotateZ = value[2]; } else { transform.rotate = value; }; break; case 'scale': if (isArray) { ln = value.length; if (ln == 0) { break; } transform.scaleX = value[0]; if (ln == 1) { break; } transform.scaleY = value[1]; if (ln == 2) { break; } transform.scaleZ = value[2]; } else { transform.scaleX = value; transform.scaleY = value; }; break; case 'skew': if (isArray) { ln = value.length; if (ln == 0) { break; } transform.skewX = value[0]; if (ln == 1) { break; } transform.skewY = value[1]; } else { transform.skewX = value; }; break; default: transform[name] = value; } } else { for (key in name) { if (name.hasOwnProperty(key)) { value = name[key]; this.setTransform(key, value); } } } }, set: function(name, value) { var data = this.data, key; if (typeof name != 'string') { for (key in name) { value = name[key]; if (key === 'transform') { this.setTransform(value); } else { data[key] = value; } } } else { if (name === 'transform') { this.setTransform(value); } else { data[name] = value; } } return this; }, unset: function(name) { var data = this.data; if (data.hasOwnProperty(name)) { delete data[name]; } return this; }, getData: function() { return this.data; } }); Ext.define('Ext.fx.animation.Abstract', { extend: 'Ext.Evented', isAnimation: true, requires: [ 'Ext.fx.State' ], config: { name: '', element: null, before: null, from: {}, to: {}, after: null, states: {}, duration: 300, easing: 'linear', iteration: 1, direction: 'normal', delay: 0, onBeforeStart: null, onEnd: null, onBeforeEnd: null, scope: null, reverse: null, preserveEndState: false, replacePrevious: true }, STATE_FROM: '0%', STATE_TO: '100%', DIRECTION_UP: 'up', DIRECTION_DOWN: 'down', DIRECTION_LEFT: 'left', DIRECTION_RIGHT: 'right', stateNameRegex: /^(?:[\d\.]+)%$/, constructor: function() { this.states = {}; this.callParent(arguments); return this; }, applyElement: function(element) { return Ext.get(element); }, applyBefore: function(before, current) { if (before) { return Ext.factory(before, Ext.fx.State, current); } }, applyAfter: function(after, current) { if (after) { return Ext.factory(after, Ext.fx.State, current); } }, setFrom: function(from) { return this.setState(this.STATE_FROM, from); }, setTo: function(to) { return this.setState(this.STATE_TO, to); }, getFrom: function() { return this.getState(this.STATE_FROM); }, getTo: function() { return this.getState(this.STATE_TO); }, setStates: function(states) { var validNameRegex = this.stateNameRegex, name; for (name in states) { if (validNameRegex.test(name)) { this.setState(name, states[name]); } } return this; }, getStates: function() { return this.states; }, end: function() { this.stop(); }, stop: function() { this.fireEvent('stop', this); }, destroy: function() { this.stop(); this.callParent(); }, setState: function(name, state) { var states = this.getStates(), stateInstance; stateInstance = Ext.factory(state, Ext.fx.State, states[name]); if (stateInstance) { states[name] = stateInstance; } else if (name === this.STATE_TO) { Ext.Logger.error("Setting and invalid '100%' / 'to' state of: " + state); } return this; }, getState: function(name) { return this.getStates()[name]; }, getData: function() { var states = this.getStates(), statesData = {}, before = this.getBefore(), after = this.getAfter(), from = states[this.STATE_FROM], to = states[this.STATE_TO], fromData = from.getData(), toData = to.getData(), data, name, state; for (name in states) { if (states.hasOwnProperty(name)) { state = states[name]; data = state.getData(); statesData[name] = data; } } if (Ext.browser.is.AndroidStock2) { statesData['0.0001%'] = fromData; } return { before: before ? before.getData() : {}, after: after ? after.getData() : {}, states: statesData, from: fromData, to: toData, duration: this.getDuration(), iteration: this.getIteration(), direction: this.getDirection(), easing: this.getEasing(), delay: this.getDelay(), onEnd: this.getOnEnd(), onBeforeEnd: this.getOnBeforeEnd(), onBeforeStart: this.getOnBeforeStart(), scope: this.getScope(), preserveEndState: this.getPreserveEndState(), replacePrevious: this.getReplacePrevious() }; } }); Ext.define('Ext.fx.animation.Slide', { extend: 'Ext.fx.animation.Abstract', alternateClassName: 'Ext.fx.animation.SlideIn', alias: [ 'animation.slide', 'animation.slideIn' ], config: { direction: 'left', out: false, offset: 0, easing: 'auto', containerBox: 'auto', elementBox: 'auto', isElementBoxFit: true, useCssTransform: true }, reverseDirectionMap: { up: 'down', down: 'up', left: 'right', right: 'left' }, applyEasing: function(easing) { if (easing === 'auto') { return 'ease-' + ((this.getOut()) ? 'in' : 'out'); } return easing; }, getContainerBox: function() { var box = this._containerBox; if (box === 'auto') { box = this.getElement().getParent().getBox(); } return box; }, getElementBox: function() { var box = this._elementBox; if (this.getIsElementBoxFit()) { return this.getContainerBox(); } if (box === 'auto') { box = this.getElement().getBox(); } return box; }, getData: function() { var elementBox = this.getElementBox(), containerBox = this.getContainerBox(), box = elementBox ? elementBox : containerBox, from = this.getFrom(), to = this.getTo(), out = this.getOut(), offset = this.getOffset(), direction = this.getDirection(), useCssTransform = this.getUseCssTransform(), reverse = this.getReverse(), translateX = 0, translateY = 0, fromX, fromY, toX, toY; if (reverse) { direction = this.reverseDirectionMap[direction]; } switch (direction) { case this.DIRECTION_UP: if (out) { translateY = containerBox.top - box.top - box.height - offset; } else { translateY = containerBox.bottom - box.bottom + box.height + offset; }; break; case this.DIRECTION_DOWN: if (out) { translateY = containerBox.bottom - box.bottom + box.height + offset; } else { translateY = containerBox.top - box.height - box.top - offset; }; break; case this.DIRECTION_RIGHT: if (out) { translateX = containerBox.right - box.right + box.width + offset; } else { translateX = containerBox.left - box.left - box.width - offset; }; break; case this.DIRECTION_LEFT: if (out) { translateX = containerBox.left - box.left - box.width - offset; } else { translateX = containerBox.right - box.right + box.width + offset; }; break; } fromX = (out) ? 0 : translateX; fromY = (out) ? 0 : translateY; if (useCssTransform) { from.setTransform({ translateX: fromX, translateY: fromY }); } else { from.set('left', fromX); from.set('top', fromY); } toX = (out) ? translateX : 0; toY = (out) ? translateY : 0; if (useCssTransform) { to.setTransform({ translateX: toX, translateY: toY }); } else { to.set('left', toX); to.set('top', toY); } return this.callParent(arguments); } }); Ext.define('Ext.fx.animation.SlideOut', { extend: 'Ext.fx.animation.Slide', alias: [ 'animation.slideOut' ], config: { out: true } }); Ext.define('Ext.fx.animation.Fade', { extend: 'Ext.fx.animation.Abstract', alternateClassName: 'Ext.fx.animation.FadeIn', alias: [ 'animation.fade', 'animation.fadeIn' ], config: { out: false, before: { display: null, opacity: 0 }, after: { opacity: null }, reverse: null }, updateOut: function(newOut) { var to = this.getTo(), from = this.getFrom(); if (newOut) { from.set('opacity', 1); to.set('opacity', 0); } else { from.set('opacity', 0); to.set('opacity', 1); } } }); Ext.define('Ext.fx.animation.FadeOut', { extend: 'Ext.fx.animation.Fade', alias: 'animation.fadeOut', config: { out: true, before: {} } }); Ext.define('Ext.fx.animation.Flip', { extend: 'Ext.fx.animation.Abstract', alias: 'animation.flip', config: { easing: 'ease-in', direction: 'right', half: false, out: null }, getData: function() { var from = this.getFrom(), to = this.getTo(), direction = this.getDirection(), out = this.getOut(), half = this.getHalf(), rotate = (half) ? 90 : 180, fromScale = 1, toScale = 1, fromRotateX = 0, fromRotateY = 0, toRotateX = 0, toRotateY = 0; if (out) { toScale = 0.8; } else { fromScale = 0.8; } switch (direction) { case this.DIRECTION_UP: if (out) { toRotateX = rotate; } else { fromRotateX = -rotate; }; break; case this.DIRECTION_DOWN: if (out) { toRotateX = -rotate; } else { fromRotateX = rotate; }; break; case this.DIRECTION_RIGHT: if (out) { toRotateY = rotate; } else { fromRotateY = -rotate; }; break; case this.DIRECTION_LEFT: if (out) { toRotateY = -rotate; } else { fromRotateY = rotate; }; break; } from.setTransform({ rotateX: fromRotateX, rotateY: fromRotateY, scale: fromScale }); to.setTransform({ rotateX: toRotateX, rotateY: toRotateY, scale: toScale }); return this.callParent(arguments); } }); Ext.define('Ext.fx.animation.Pop', { extend: 'Ext.fx.animation.Abstract', alias: [ 'animation.pop', 'animation.popIn' ], alternateClassName: 'Ext.fx.animation.PopIn', config: { out: false, before: { display: null, opacity: 0 }, after: { opacity: null } }, getData: function() { var to = this.getTo(), from = this.getFrom(), out = this.getOut(); if (out) { from.set('opacity', 1); from.setTransform({ scale: 1 }); to.set('opacity', 0); to.setTransform({ scale: 0 }); } else { from.set('opacity', 0); from.setTransform({ scale: 0 }); to.set('opacity', 1); to.setTransform({ scale: 1 }); } return this.callParent(arguments); } }); Ext.define('Ext.fx.animation.PopOut', { extend: 'Ext.fx.animation.Pop', alias: 'animation.popOut', config: { out: true, before: {} } }); Ext.define('Ext.fx.Animation', { requires: [ 'Ext.fx.animation.Slide', 'Ext.fx.animation.SlideOut', 'Ext.fx.animation.Fade', 'Ext.fx.animation.FadeOut', 'Ext.fx.animation.Flip', 'Ext.fx.animation.Pop', 'Ext.fx.animation.PopOut' ], constructor: function(config) { var defaultClass = Ext.fx.animation.Abstract, type; if (typeof config == 'string') { type = config; config = {}; } else if (config && config.type) { type = config.type; } if (type) { if (Ext.browser.is.AndroidStock2) { if (type == 'pop') { type = 'fade'; } if (type == 'popIn') { type = 'fadeIn'; } if (type == 'popOut') { type = 'fadeOut'; } } defaultClass = Ext.ClassManager.getByAlias('animation.' + type); if (!defaultClass) { Ext.Logger.error("Invalid animation type of: '" + type + "'"); } } return Ext.factory(config, defaultClass); } }); Ext.define('Ext.fx.runner.Css', { extend: 'Ext.Evented', requires: [ 'Ext.fx.Animation' ], prefixedProperties: { 'transform': true, 'transform-origin': true, 'perspective': true, 'transform-style': true, 'transition': true, 'transition-property': true, 'transition-duration': true, 'transition-timing-function': true, 'transition-delay': true, 'animation': true, 'animation-name': true, 'animation-duration': true, 'animation-iteration-count': true, 'animation-direction': true, 'animation-timing-function': true, 'animation-delay': true }, lengthProperties: { 'top': true, 'right': true, 'bottom': true, 'left': true, 'width': true, 'height': true, 'max-height': true, 'max-width': true, 'min-height': true, 'min-width': true, 'margin-bottom': true, 'margin-left': true, 'margin-right': true, 'margin-top': true, 'padding-bottom': true, 'padding-left': true, 'padding-right': true, 'padding-top': true, 'border-bottom-width': true, 'border-left-width': true, 'border-right-width': true, 'border-spacing': true, 'border-top-width': true, 'border-width': true, 'outline-width': true, 'letter-spacing': true, 'line-height': true, 'text-indent': true, 'word-spacing': true, 'font-size': true, 'translate': true, 'translateX': true, 'translateY': true, 'translateZ': true, 'translate3d': true }, durationProperties: { 'transition-duration': true, 'transition-delay': true, 'animation-duration': true, 'animation-delay': true }, angleProperties: { rotate: true, rotateX: true, rotateY: true, rotateZ: true, skew: true, skewX: true, skewY: true }, lengthUnitRegex: /([a-z%]*)$/, DEFAULT_UNIT_LENGTH: 'px', DEFAULT_UNIT_ANGLE: 'deg', DEFAULT_UNIT_DURATION: 'ms', formattedNameCache: {}, constructor: function() { var supports3dTransform = Ext.feature.has.Css3dTransforms; if (supports3dTransform) { this.transformMethods = [ 'translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'skewX', 'skewY', 'scaleX', 'scaleY', 'scaleZ' ]; } else { this.transformMethods = [ 'translateX', 'translateY', 'rotate', 'skewX', 'skewY', 'scaleX', 'scaleY' ]; } this.vendorPrefix = Ext.browser.getStyleDashPrefix(); this.ruleStylesCache = {}; this.callParent(); }, getStyleSheet: function() { var styleSheet = this.styleSheet, styleElement, styleSheets; if (!styleSheet) { styleElement = document.createElement('style'); styleElement.type = 'text/css'; (document.head || document.getElementsByTagName('head')[0]).appendChild(styleElement); styleSheets = document.styleSheets; this.styleSheet = styleSheet = styleSheets[styleSheets.length - 1]; } return styleSheet; }, applyRules: function(selectors) { var styleSheet = this.getStyleSheet(), ruleStylesCache = this.ruleStylesCache, rules = styleSheet.cssRules, selector, properties, ruleStyle, ruleStyleCache, rulesLength, name, value; for (selector in selectors) { properties = selectors[selector]; ruleStyle = ruleStylesCache[selector]; if (ruleStyle === undefined) { rulesLength = rules.length; styleSheet.insertRule(selector + '{}', rulesLength); ruleStyle = ruleStylesCache[selector] = rules.item(rulesLength).style; } ruleStyleCache = ruleStyle.$cache; if (!ruleStyleCache) { ruleStyleCache = ruleStyle.$cache = {}; } for (name in properties) { value = this.formatValue(properties[name], name); name = this.formatName(name); if (ruleStyleCache[name] !== value) { ruleStyleCache[name] = value; if (value === null) { ruleStyle.removeProperty(name); } else { ruleStyle.setProperty(name, value, 'important'); } } } } return this; }, applyStyles: function(styles) { var id, element, elementStyle, properties, name, value; for (id in styles) { if (styles.hasOwnProperty(id)) { element = document.getElementById(id); if (!element) { return this; } elementStyle = element.style; properties = styles[id]; for (name in properties) { if (properties.hasOwnProperty(name)) { value = this.formatValue(properties[name], name); name = this.formatName(name); if (value === null) { elementStyle.removeProperty(name); } else { elementStyle.setProperty(name, value, 'important'); } } } } } return this; }, formatName: function(name) { var cache = this.formattedNameCache, formattedName = cache[name]; if (!formattedName) { if ((Ext.os.is.Tizen || !Ext.feature.has.CssTransformNoPrefix) && this.prefixedProperties[name]) { formattedName = this.vendorPrefix + name; } else { formattedName = name; } cache[name] = formattedName; } return formattedName; }, formatValue: function(value, name) { var type = typeof value, lengthUnit = this.DEFAULT_UNIT_LENGTH, transformMethods, method, i, ln, transformValues, values, unit; if (value === null) { return ''; } if (type == 'string') { if (this.lengthProperties[name]) { unit = value.match(this.lengthUnitRegex)[1]; if (unit.length > 0) { if (unit !== lengthUnit) { Ext.Logger.error("Length unit: '" + unit + "' in value: '" + value + "' of property: '" + name + "' is not " + "valid for animation. Only 'px' is allowed"); } } else { return value + lengthUnit; } } return value; } else if (type == 'number') { if (value == 0) { return '0'; } if (this.lengthProperties[name]) { return value + lengthUnit; } if (this.angleProperties[name]) { return value + this.DEFAULT_UNIT_ANGLE; } if (this.durationProperties[name]) { return value + this.DEFAULT_UNIT_DURATION; } } else if (name === 'transform') { transformMethods = this.transformMethods; transformValues = []; for (i = 0 , ln = transformMethods.length; i < ln; i++) { method = transformMethods[i]; transformValues.push(method + '(' + this.formatValue(value[method], method) + ')'); } return transformValues.join(' '); } else if (Ext.isArray(value)) { values = []; for (i = 0 , ln = value.length; i < ln; i++) { values.push(this.formatValue(value[i], name)); } return (values.length > 0) ? values.join(', ') : 'none'; } return value; } }); Ext.define('Ext.fx.runner.CssTransition', { extend: 'Ext.fx.runner.Css', requires: [ 'Ext.AnimationQueue' ], alternateClassName: 'Ext.Animator', singleton: true, listenersAttached: false, constructor: function() { this.runningAnimationsData = {}; return this.callParent(arguments); }, attachListeners: function() { this.listenersAttached = true; Ext.getWin().on('transitionend', 'onTransitionEnd', this); }, onTransitionEnd: function(e) { var target = e.target, id = target.id; if (id && this.runningAnimationsData.hasOwnProperty(id)) { this.refreshRunningAnimationsData(Ext.get(target), [ e.browserEvent.propertyName ]); } }, onAnimationEnd: function(element, data, animation, isInterrupted, isReplaced) { var id = element.getId(), runningData = this.runningAnimationsData[id], endRules = {}, endData = {}, runningNameMap, toPropertyNames, i, ln, name; animation.un('stop', 'onAnimationStop', this); if (runningData) { runningNameMap = runningData.nameMap; } endRules[id] = endData; if (data.onBeforeEnd) { data.onBeforeEnd.call(data.scope || this, element, isInterrupted); } animation.fireEvent('animationbeforeend', animation, element, isInterrupted); this.fireEvent('animationbeforeend', this, animation, element, isInterrupted); if (isReplaced || (!isInterrupted && !data.preserveEndState)) { toPropertyNames = data.toPropertyNames; for (i = 0 , ln = toPropertyNames.length; i < ln; i++) { name = toPropertyNames[i]; if (runningNameMap && !runningNameMap.hasOwnProperty(name)) { endData[name] = null; } } } if (data.after) { Ext.merge(endData, data.after); } this.applyStyles(endRules); if (data.onEnd) { data.onEnd.call(data.scope || this, element, isInterrupted); } animation.fireEvent('animationend', animation, element, isInterrupted); this.fireEvent('animationend', this, animation, element, isInterrupted); Ext.AnimationQueue.stop(Ext.emptyFn, animation); }, onAllAnimationsEnd: function(element) { var id = element.getId(), endRules = {}; delete this.runningAnimationsData[id]; endRules[id] = { 'transition-property': null, 'transition-duration': null, 'transition-timing-function': null, 'transition-delay': null }; this.applyStyles(endRules); this.fireEvent('animationallend', this, element); }, hasRunningAnimations: function(element) { var id = element.getId(), runningAnimationsData = this.runningAnimationsData; return runningAnimationsData.hasOwnProperty(id) && runningAnimationsData[id].sessions.length > 0; }, refreshRunningAnimationsData: function(element, propertyNames, interrupt, replace) { var id = element.getId(), runningAnimationsData = this.runningAnimationsData, runningData = runningAnimationsData[id]; if (!runningData) { return; } var nameMap = runningData.nameMap, nameList = runningData.nameList, sessions = runningData.sessions, ln, j, subLn, name, i, session, map, list, hasCompletedSession = false; interrupt = Boolean(interrupt); replace = Boolean(replace); if (!sessions) { return this; } ln = sessions.length; if (ln === 0) { return this; } if (replace) { runningData.nameMap = {}; nameList.length = 0; for (i = 0; i < ln; i++) { session = sessions[i]; this.onAnimationEnd(element, session.data, session.animation, interrupt, replace); } sessions.length = 0; } else { for (i = 0; i < ln; i++) { session = sessions[i]; map = session.map; list = session.list; for (j = 0 , subLn = propertyNames.length; j < subLn; j++) { name = propertyNames[j]; if (map[name]) { delete map[name]; Ext.Array.remove(list, name); session.length--; if (--nameMap[name] == 0) { delete nameMap[name]; Ext.Array.remove(nameList, name); } } } if (session.length == 0) { sessions.splice(i, 1); i--; ln--; hasCompletedSession = true; this.onAnimationEnd(element, session.data, session.animation, interrupt); } } } if (!replace && !interrupt && sessions.length == 0 && hasCompletedSession) { this.onAllAnimationsEnd(element); } }, getRunningData: function(id) { var runningAnimationsData = this.runningAnimationsData; if (!runningAnimationsData.hasOwnProperty(id)) { runningAnimationsData[id] = { nameMap: {}, nameList: [], sessions: [] }; } return runningAnimationsData[id]; }, getTestElement: function() { var testElement = this.testElement, iframe, iframeDocument, iframeStyle; if (!testElement) { iframe = document.createElement('iframe'); iframe.setAttribute('tabindex', -1); iframeStyle = iframe.style; iframeStyle.setProperty('visibility', 'hidden', 'important'); iframeStyle.setProperty('width', '0px', 'important'); iframeStyle.setProperty('height', '0px', 'important'); iframeStyle.setProperty('position', 'absolute', 'important'); iframeStyle.setProperty('border', '0px', 'important'); iframeStyle.setProperty('zIndex', '-1000', 'important'); document.body.appendChild(iframe); iframeDocument = iframe.contentDocument; iframeDocument.open(); iframeDocument.writeln(''); iframeDocument.close(); this.testElement = testElement = iframeDocument.createElement('div'); testElement.style.setProperty('position', 'absolute', 'important'); iframeDocument.body.appendChild(testElement); this.testElementComputedStyle = window.getComputedStyle(testElement); } return testElement; }, getCssStyleValue: function(name, value) { var testElement = this.getTestElement(), computedStyle = this.testElementComputedStyle, style = testElement.style; style.setProperty(name, value); if (Ext.browser.is.Firefox) { testElement.offsetHeight; } value = computedStyle.getPropertyValue(name); style.removeProperty(name); return value; }, run: function(animations) { var me = this, isLengthPropertyMap = this.lengthProperties, fromData = {}, toData = {}, data = {}, element, elementId, from, to, before, fromPropertyNames, toPropertyNames, doApplyTo, message, runningData, elementData, i, j, ln, animation, propertiesLength, sessionNameMap, computedStyle, formattedName, name, toFormattedValue, computedValue, fromFormattedValue, isLengthProperty, runningNameMap, runningNameList, runningSessions, runningSession; if (!this.listenersAttached) { this.attachListeners(); } animations = Ext.Array.from(animations); for (i = 0 , ln = animations.length; i < ln; i++) { animation = animations[i]; animation = Ext.factory(animation, Ext.fx.Animation); element = animation.getElement(); Ext.AnimationQueue.start(Ext.emptyFn, animation); computedStyle = window.getComputedStyle(element.dom); elementId = element.getId(); data = Ext.merge({}, animation.getData()); if (animation.onBeforeStart) { animation.onBeforeStart.call(animation.scope || this, element); } animation.fireEvent('animationstart', animation); this.fireEvent('animationstart', this, animation); data[elementId] = data; before = data.before; from = data.from; to = data.to; data.fromPropertyNames = fromPropertyNames = []; data.toPropertyNames = toPropertyNames = []; for (name in to) { if (to.hasOwnProperty(name)) { to[name] = toFormattedValue = this.formatValue(to[name], name); formattedName = this.formatName(name); isLengthProperty = isLengthPropertyMap.hasOwnProperty(name); if (!isLengthProperty) { toFormattedValue = this.getCssStyleValue(formattedName, toFormattedValue); } if (from.hasOwnProperty(name)) { from[name] = fromFormattedValue = this.formatValue(from[name], name); if (!isLengthProperty) { fromFormattedValue = this.getCssStyleValue(formattedName, fromFormattedValue); } if (toFormattedValue !== fromFormattedValue) { fromPropertyNames.push(formattedName); toPropertyNames.push(formattedName); } } else { computedValue = computedStyle.getPropertyValue(formattedName); if (toFormattedValue !== computedValue) { toPropertyNames.push(formattedName); } } } } propertiesLength = toPropertyNames.length; if (propertiesLength === 0) { this.onAnimationEnd(element, data, animation); continue; } runningData = this.getRunningData(elementId); runningSessions = runningData.sessions; if (runningSessions.length > 0) { this.refreshRunningAnimationsData(element, Ext.Array.merge(fromPropertyNames, toPropertyNames), true, data.replacePrevious); } runningNameMap = runningData.nameMap; runningNameList = runningData.nameList; sessionNameMap = {}; for (j = 0; j < propertiesLength; j++) { name = toPropertyNames[j]; sessionNameMap[name] = true; if (!runningNameMap.hasOwnProperty(name)) { runningNameMap[name] = 1; runningNameList.push(name); } else { runningNameMap[name]++; } } runningSession = { element: element, map: sessionNameMap, list: toPropertyNames.slice(), length: propertiesLength, data: data, animation: animation }; runningSessions.push(runningSession); animation.on('stop', 'onAnimationStop', this); elementData = Ext.apply({}, before); Ext.apply(elementData, from); if (runningNameList.length > 0) { fromPropertyNames = Ext.Array.difference(runningNameList, fromPropertyNames); toPropertyNames = Ext.Array.merge(fromPropertyNames, toPropertyNames); elementData['transition-property'] = fromPropertyNames; } fromData[elementId] = elementData; toData[elementId] = Ext.apply({}, to); toData[elementId]['transition-property'] = toPropertyNames; toData[elementId]['transition-duration'] = data.duration; toData[elementId]['transition-timing-function'] = data.easing; toData[elementId]['transition-delay'] = data.delay; animation.startTime = Date.now(); } message = this.$className; this.applyStyles(fromData); doApplyTo = function(e) { if (e.data === message && e.source === window) { window.removeEventListener('message', doApplyTo, false); me.applyStyles(toData); } }; if (Ext.browser.is.IE) { Ext.Function.requestAnimationFrame(function() { window.addEventListener('message', doApplyTo, false); window.postMessage(message, '*'); }); } else { window.addEventListener('message', doApplyTo, false); window.postMessage(message, '*'); } }, onAnimationStop: function(animation) { var runningAnimationsData = this.runningAnimationsData, id, runningData, sessions, i, ln, session; for (id in runningAnimationsData) { if (runningAnimationsData.hasOwnProperty(id)) { runningData = runningAnimationsData[id]; sessions = runningData.sessions; for (i = 0 , ln = sessions.length; i < ln; i++) { session = sessions[i]; if (session.animation === animation) { this.refreshRunningAnimationsData(session.element, session.list.slice(), false); } } } } } }); Ext.define('Ext.fx.Runner', { requires: [ 'Ext.fx.runner.CssTransition' ], constructor: function() { return new Ext.fx.runner.CssTransition(); } }); Ext.define('Ext.fx.animation.Cube', { extend: 'Ext.fx.animation.Abstract', alias: 'animation.cube', config: { before: {}, after: {}, direction: 'right', out: false }, getData: function() { var to = this.getTo(), from = this.getFrom(), before = this.getBefore(), after = this.getAfter(), out = this.getOut(), direction = this.getDirection(), el = this.getElement(), elW = el.getWidth(), elH = el.getHeight(), origin = out ? '100% 100%' : '0% 0%', fromOpacity = 1, toOpacity = 1, transformFrom = { rotateY: 0, translateZ: 0 }, transformTo = { rotateY: 0, translateZ: 0 }; if (direction == "left" || direction == "right") { if (out) { toOpacity = 0.5; transformTo.translateZ = elW; transformTo.rotateY = -90; } else { fromOpacity = 0.5; transformFrom.translateZ = elW; transformFrom.rotateY = 90; } } before['transform-origin'] = origin; after['transform-origin'] = null; to.set('transform', transformTo); from.set('transform', transformFrom); from.set('opacity', fromOpacity); to.set('opacity', toOpacity); return this.callParent(arguments); } }); Ext.define('Ext.fx.animation.Wipe', { extend: 'Ext.fx.Animation', alternateClassName: 'Ext.fx.animation.WipeIn', config: { easing: 'ease-out', direction: 'right', out: false }, refresh: function() { var me = this, el = me.getElement(), elBox = el.dom.getBoundingClientRect(), elWidth = elBox.width, elHeight = elBox.height, from = me.getFrom(), to = me.getTo(), out = me.getOut(), direction = me.getDirection(), maskFromX = 0, maskFromY = 0, maskToX = 0, maskToY = 0, mask, tmp; switch (direction) { case 'up': if (out) { mask = '-webkit-gradient(linear, left top, left bottom, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))'; maskFromY = elHeight * 3 + 'px'; maskToY = elHeight + 'px'; } else { mask = '-webkit-gradient(linear, left top, left bottom, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))'; maskFromY = -elHeight * 2 + 'px'; maskToY = 0; }; break; case 'down': if (out) { mask = '-webkit-gradient(linear, left top, left bottom, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))'; maskFromY = -elHeight * 2 + 'px'; maskToY = 0; } else { mask = '-webkit-gradient(linear, left top, left bottom, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))'; maskFromY = elHeight * 3 + 'px'; maskToY = elHeight + 'px'; }; break; case 'right': if (out) { mask = '-webkit-gradient(linear, right top, left top, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))'; maskFromX = -elWidth * 2 + 'px'; maskToX = 0; } else { mask = '-webkit-gradient(linear, right top, left top, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))'; maskToX = -elWidth * 2 + 'px'; }; break; case 'left': if (out) { mask = '-webkit-gradient(linear, right top, left top, from(transparent), to(#000), color-stop(66%, #000), color-stop(33%, transparent))'; maskToX = -elWidth * 2 + 'px'; } else { mask = '-webkit-gradient(linear, right top, left top, from(#000), to(transparent), color-stop(33%, #000), color-stop(66%, transparent))'; maskFromX = -elWidth * 2 + 'px'; maskToX = 0; }; break; } if (!out) { tmp = maskFromY; maskFromY = maskToY; maskToY = tmp; tmp = maskFromX; maskFromX = maskToX; maskToX = tmp; } from.set('mask-image', mask); from.set('mask-size', elWidth * 3 + 'px ' + elHeight * 3 + 'px'); from.set('mask-position-x', maskFromX); from.set('mask-position-y', maskFromY); to.set('mask-position-x', maskToX); to.set('mask-position-y', maskToY); } }); Ext.define('Ext.fx.animation.WipeOut', { extend: 'Ext.fx.animation.Wipe', config: { out: true } }); Ext.define('Ext.fx.easing.EaseIn', { extend: 'Ext.fx.easing.Linear', alias: 'easing.ease-in', config: { exponent: 4, duration: 1500 }, getValue: function() { var deltaTime = Ext.Date.now() - this.getStartTime(), duration = this.getDuration(), startValue = this.getStartValue(), endValue = this.getEndValue(), distance = this.distance, theta = deltaTime / duration, thetaEnd = Math.pow(theta, this.getExponent()), currentValue = startValue + (thetaEnd * distance); if (deltaTime >= duration) { this.isEnded = true; return endValue; } return currentValue; } }); Ext.define('Ext.fx.easing.Easing', { requires: [ 'Ext.fx.easing.Linear' ], constructor: function(easing) { return Ext.factory(easing, Ext.fx.easing.Linear, null, 'easing'); } }); Ext.define('Ext.fx.layout.card.Abstract', { extend: 'Ext.Evented', isAnimation: true, config: { direction: 'left', duration: null, reverse: null, layout: null }, updateLayout: function() { this.enable(); }, enable: function() { var layout = this.getLayout(); if (layout) { layout.onBefore('activeitemchange', 'onActiveItemChange', this); } }, disable: function() { var layout = this.getLayout(); if (this.isAnimating) { this.stopAnimation(); } if (layout) { layout.unBefore('activeitemchange', 'onActiveItemChange', this); } }, onActiveItemChange: Ext.emptyFn, destroy: function() { var layout = this.getLayout(); if (this.isAnimating) { this.stopAnimation(); } if (layout) { layout.unBefore('activeitemchange', 'onActiveItemChange', this); } this.setLayout(null); if (this.observableId) { this.fireEvent('destroy', this); this.clearListeners(); this.clearManagedListeners(); } } }); Ext.define('Ext.fx.layout.card.Style', { extend: 'Ext.fx.layout.card.Abstract', requires: [ 'Ext.fx.Animation' ], config: { inAnimation: { before: { visibility: null }, preserveEndState: false, replacePrevious: true }, outAnimation: { preserveEndState: false, replacePrevious: true } }, constructor: function(config) { var inAnimation, outAnimation; this.callParent([ config ]); this.endAnimationCounter = 0; inAnimation = this.getInAnimation(); outAnimation = this.getOutAnimation(); inAnimation.on('animationend', 'incrementEnd', this); outAnimation.on('animationend', 'incrementEnd', this); }, updateDirection: function(direction) { this.getInAnimation().setDirection(direction); this.getOutAnimation().setDirection(direction); }, updateDuration: function(duration) { this.getInAnimation().setDuration(duration); this.getOutAnimation().setDuration(duration); }, updateReverse: function(reverse) { this.getInAnimation().setReverse(reverse); this.getOutAnimation().setReverse(reverse); }, incrementEnd: function() { this.endAnimationCounter++; if (this.endAnimationCounter > 1) { this.endAnimationCounter = 0; this.fireEvent('animationend', this); } }, applyInAnimation: function(animation, inAnimation) { return Ext.factory(animation, Ext.fx.Animation, inAnimation); }, applyOutAnimation: function(animation, outAnimation) { return Ext.factory(animation, Ext.fx.Animation, outAnimation); }, updateInAnimation: function(animation) { animation.setScope(this); }, updateOutAnimation: function(animation) { animation.setScope(this); }, onActiveItemChange: function(cardLayout, newItem, oldItem, options, controller) { var inAnimation = this.getInAnimation(), outAnimation = this.getOutAnimation(), inElement, outElement; if (newItem && oldItem && oldItem.isPainted()) { inElement = newItem.renderElement; outElement = oldItem.renderElement; inAnimation.setElement(inElement); outAnimation.setElement(outElement); outAnimation.setOnBeforeEnd(function(element, interrupted) { if (interrupted || Ext.Animator.hasRunningAnimations(element)) { controller.firingArguments[1] = null; controller.firingArguments[2] = null; } }); outAnimation.setOnEnd(function() { controller.resume(); }); inElement.dom.style.setProperty('visibility', 'hidden', 'important'); newItem.show(); Ext.Animator.run([ outAnimation, inAnimation ]); controller.pause(); } }, destroy: function() { Ext.destroy(this.getInAnimation(), this.getOutAnimation()); this.callParent(arguments); } }); Ext.define('Ext.fx.layout.card.Slide', { extend: 'Ext.fx.layout.card.Style', alias: 'fx.layout.card.slide', config: { inAnimation: { type: 'slide', easing: 'ease-out' }, outAnimation: { type: 'slide', easing: 'ease-out', out: true } }, updateReverse: function(reverse) { this.getInAnimation().setReverse(reverse); this.getOutAnimation().setReverse(reverse); } }); Ext.define('Ext.fx.layout.card.Cover', { extend: 'Ext.fx.layout.card.Style', alias: 'fx.layout.card.cover', config: { reverse: null, inAnimation: { before: { 'z-index': 100 }, after: { 'z-index': 0 }, type: 'slide', easing: 'ease-out' }, outAnimation: { easing: 'ease-out', from: { opacity: 0.99 }, to: { opacity: 1 }, out: true } }, updateReverse: function(reverse) { this.getInAnimation().setReverse(reverse); this.getOutAnimation().setReverse(reverse); } }); Ext.define('Ext.fx.layout.card.Reveal', { extend: 'Ext.fx.layout.card.Style', alias: 'fx.layout.card.reveal', config: { inAnimation: { easing: 'ease-out', from: { opacity: 0.99 }, to: { opacity: 1 } }, outAnimation: { before: { 'z-index': 100 }, after: { 'z-index': 0 }, type: 'slide', easing: 'ease-out', out: true } }, updateReverse: function(reverse) { this.getInAnimation().setReverse(reverse); this.getOutAnimation().setReverse(reverse); } }); Ext.define('Ext.fx.layout.card.Fade', { extend: 'Ext.fx.layout.card.Style', alias: 'fx.layout.card.fade', config: { reverse: null, inAnimation: { type: 'fade', easing: 'ease-out' }, outAnimation: { type: 'fade', easing: 'ease-out', out: true } } }); Ext.define('Ext.fx.layout.card.Flip', { extend: 'Ext.fx.layout.card.Style', alias: 'fx.layout.card.flip', config: { duration: 500, inAnimation: { type: 'flip', half: true, easing: 'ease-out', before: { 'backface-visibility': 'hidden' }, after: { 'backface-visibility': null } }, outAnimation: { type: 'flip', half: true, easing: 'ease-in', before: { 'backface-visibility': 'hidden' }, after: { 'backface-visibility': null }, out: true } }, onActiveItemChange: function(cardLayout, newItem, oldItem, options, controller) { var parent = newItem.element.getParent(); parent.addCls(Ext.baseCSSPrefix + 'layout-card-perspective'); this.on('animationend', function() { parent.removeCls(Ext.baseCSSPrefix + 'layout-card-perspective'); }, this, { single: true }); this.callParent(arguments); }, updateDuration: function(duration) { var halfDuration = duration / 2, inAnimation = this.getInAnimation(), outAnimation = this.getOutAnimation(); inAnimation.setDelay(halfDuration); inAnimation.setDuration(halfDuration); outAnimation.setDuration(halfDuration); } }); Ext.define('Ext.fx.layout.card.Pop', { extend: 'Ext.fx.layout.card.Style', alias: 'fx.layout.card.pop', config: { duration: 500, inAnimation: { type: 'pop', easing: 'ease-out' }, outAnimation: { type: 'pop', easing: 'ease-in', out: true } }, updateDuration: function(duration) { var halfDuration = duration / 2, inAnimation = this.getInAnimation(), outAnimation = this.getOutAnimation(); inAnimation.setDelay(halfDuration); inAnimation.setDuration(halfDuration); outAnimation.setDuration(halfDuration); } }); Ext.define('Ext.fx.layout.card.Scroll', { extend: 'Ext.fx.layout.card.Abstract', requires: [ 'Ext.fx.easing.Linear' ], alias: 'fx.layout.card.scroll', config: { duration: 150 }, constructor: function(config) { this.initConfig(config); }, getEasing: function() { var easing = this.easing; if (!easing) { this.easing = easing = new Ext.fx.easing.Linear(); } return easing; }, updateDuration: function(duration) { this.getEasing().setDuration(duration); }, onActiveItemChange: function(cardLayout, newItem, oldItem, options, controller) { var direction = this.getDirection(), easing = this.getEasing(), containerElement, inElement, outElement, containerWidth, containerHeight, reverse; if (newItem && oldItem) { if (this.isAnimating) { this.stopAnimation(); } newItem.setWidth('100%'); newItem.setHeight('100%'); containerElement = this.getLayout().container.innerElement; containerWidth = containerElement.getWidth(); containerHeight = containerElement.getHeight(); inElement = newItem.renderElement; outElement = oldItem.renderElement; this.oldItem = oldItem; this.newItem = newItem; this.currentEventController = controller; this.containerElement = containerElement; this.isReverse = reverse = this.getReverse(); newItem.show(); if (direction == 'right') { direction = 'left'; this.isReverse = reverse = !reverse; } else if (direction == 'down') { direction = 'up'; this.isReverse = reverse = !reverse; } if (direction == 'left') { if (reverse) { easing.setConfig({ startValue: containerWidth, endValue: 0 }); containerElement.dom.scrollLeft = containerWidth; outElement.setLeft(containerWidth); } else { easing.setConfig({ startValue: 0, endValue: containerWidth }); inElement.setLeft(containerWidth); } } else { if (reverse) { easing.setConfig({ startValue: containerHeight, endValue: 0 }); containerElement.dom.scrollTop = containerHeight; outElement.setTop(containerHeight); } else { easing.setConfig({ startValue: 0, endValue: containerHeight }); inElement.setTop(containerHeight); } } this.startAnimation(); controller.pause(); } }, startAnimation: function() { this.isAnimating = true; this.getEasing().setStartTime(Date.now()); Ext.AnimationQueue.start(this.doAnimationFrame, this); }, doAnimationFrame: function() { var easing = this.getEasing(), direction = this.getDirection(), scroll = 'scrollTop', value; if (direction == 'left' || direction == 'right') { scroll = 'scrollLeft'; } if (easing.isEnded) { this.stopAnimation(); } else { value = easing.getValue(); this.containerElement.dom[scroll] = value; } }, stopAnimation: function() { var me = this, direction = me.getDirection(), scroll = 'setTop', oldItem = me.oldItem, newItem = me.newItem; if (direction == 'left' || direction == 'right') { scroll = 'setLeft'; } me.currentEventController.resume(); if (me.isReverse && oldItem && oldItem.renderElement && oldItem.renderElement.dom) { oldItem.renderElement[scroll](null); } else if (newItem && newItem.renderElement && newItem.renderElement.dom) { newItem.renderElement[scroll](null); } Ext.AnimationQueue.stop(this.doAnimationFrame, this); me.isAnimating = false; me.fireEvent('animationend', me); } }); Ext.define('Ext.fx.layout.Card', { requires: [ 'Ext.fx.layout.card.Slide', 'Ext.fx.layout.card.Cover', 'Ext.fx.layout.card.Reveal', 'Ext.fx.layout.card.Fade', 'Ext.fx.layout.card.Flip', 'Ext.fx.layout.card.Pop', 'Ext.fx.layout.card.Scroll' ], constructor: function(config) { var defaultClass = Ext.fx.layout.card.Abstract, type; if (!config) { return null; } if (typeof config == 'string') { type = config; config = {}; } else if (config.type) { type = config.type; } config.elementBox = false; if (type) { if (Ext.browser.is.AndroidStock2) { if (type != 'fade') { type = 'scroll'; } } defaultClass = Ext.ClassManager.getByAlias('fx.layout.card.' + type); if (!defaultClass) { Ext.Logger.error("Unknown card animation type: '" + type + "'"); } } return Ext.factory(config, defaultClass); } }); Ext.define('Ext.fx.layout.card.Cube', { extend: 'Ext.fx.layout.card.Style', alias: 'fx.layout.card.cube', config: { reverse: null, inAnimation: { type: 'cube' }, outAnimation: { type: 'cube', out: true } } }); Ext.define('Ext.fx.layout.card.ScrollCover', { extend: 'Ext.fx.layout.card.Scroll', alias: 'fx.layout.card.scrollcover', onActiveItemChange: function(cardLayout, inItem, outItem, options, controller) { var containerElement, containerSize, xy, animConfig, inTranslate, outTranslate; this.lastController = controller; this.inItem = inItem; if (inItem && outItem) { containerElement = this.getLayout().container.innerElement; containerSize = containerElement.getSize(); xy = this.calculateXY(containerSize); animConfig = { easing: this.getEasing(), duration: this.getDuration() }; inItem.renderElement.dom.style.setProperty('visibility', 'hidden', 'important'); inTranslate = inItem.setTranslatable(true).getTranslatable(); outTranslate = outItem.setTranslatable(true).getTranslatable(); outTranslate.translate({ x: 0, y: 0 }); inTranslate.translate({ x: xy.left, y: xy.top }); inTranslate.getWrapper().dom.style.setProperty('z-index', '100', 'important'); inItem.show(); inTranslate.on({ animationstart: 'onInAnimationStart', animationend: 'onInAnimationEnd', scope: this }); inTranslate.translateAnimated({ x: 0, y: 0 }, animConfig); controller.pause(); } }, onInAnimationStart: function() { this.inItem.renderElement.dom.style.removeProperty('visibility'); }, onInAnimationEnd: function() { this.inItem.getTranslatable().getWrapper().dom.style.removeProperty('z-index'); this.lastController.resume(); } }); Ext.define('Ext.fx.layout.card.ScrollReveal', { extend: 'Ext.fx.layout.card.Scroll', alias: 'fx.layout.card.scrollreveal', onActiveItemChange: function(cardLayout, inItem, outItem, options, controller) { var containerElement, containerSize, xy, animConfig, outTranslate, inTranslate; this.lastController = controller; this.outItem = outItem; this.inItem = inItem; if (inItem && outItem) { containerElement = this.getLayout().container.innerElement; containerSize = containerElement.getSize(); xy = this.calculateXY(containerSize); animConfig = { easing: this.getEasing(), duration: this.getDuration() }; outTranslate = outItem.setTranslatable(true).getTranslatable(); inTranslate = inItem.setTranslatable(true).getTranslatable(); outTranslate.getWrapper().dom.style.setProperty('z-index', '100', 'important'); outTranslate.translate({ x: 0, y: 0 }); inTranslate.translate({ x: 0, y: 0 }); inItem.show(); outTranslate.on({ animationend: 'onOutAnimationEnd', scope: this }); outTranslate.translateAnimated({ x: xy.x, y: xy.y }, animConfig); controller.pause(); } }, onOutAnimationEnd: function() { this.outItem.getTranslatable().getWrapper().dom.style.removeProperty('z-index'); this.lastController.resume(); } }); Ext.define('Ext.fx.runner.CssAnimation', { extend: 'Ext.fx.runner.Css', constructor: function() { this.runningAnimationsMap = {}; this.elementEndStates = {}; this.animationElementMap = {}; this.keyframesRulesCache = {}; this.uniqueId = 0; return this.callParent(arguments); }, attachListeners: function() { this.listenersAttached = true; Ext.getWin().on({ animationstart: 'onAnimationStart', animationend: 'onAnimationEnd', scope: this }); }, onAnimationStart: function(e) { var name = e.browserEvent.animationName, elementId = this.animationElementMap[name], animation = this.runningAnimationsMap[elementId][name], elementEndStates = this.elementEndStates, elementEndState = elementEndStates[elementId], data = {}; if (elementEndState) { delete elementEndStates[elementId]; data[elementId] = elementEndState; this.applyStyles(data); } if (animation.before) { data[elementId] = animation.before; this.applyStyles(data); } }, onAnimationEnd: function(e) { var element = e.target, name = e.browserEvent.animationName, animationElementMap = this.animationElementMap, elementId = animationElementMap[name], runningAnimationsMap = this.runningAnimationsMap, runningAnimations = runningAnimationsMap[elementId], animation = runningAnimations[name]; if (animation.onBeforeEnd) { animation.onBeforeEnd.call(animation.scope || this, element); } if (animation.onEnd) { animation.onEnd.call(animation.scope || this, element); } delete animationElementMap[name]; delete runningAnimations[name]; this.removeKeyframesRule(name); }, generateAnimationId: function() { return 'animation-' + (++this.uniqueId); }, run: function(animations) { var data = {}, elementEndStates = this.elementEndStates, animationElementMap = this.animationElementMap, runningAnimationsMap = this.runningAnimationsMap, runningAnimations, states, elementId, animationId, i, ln, animation, name, runningAnimation, names, durations, easings, delays, directions, iterations; if (!this.listenersAttached) { this.attachListeners(); } animations = Ext.Array.from(animations); for (i = 0 , ln = animations.length; i < ln; i++) { animation = animations[i]; animation = Ext.factory(animation, Ext.fx.Animation); elementId = animation.getElement().getId(); animationId = animation.getName() || this.generateAnimationId(); animationElementMap[animationId] = elementId; animation = animation.getData(); states = animation.states; this.addKeyframesRule(animationId, states); runningAnimations = runningAnimationsMap[elementId]; if (!runningAnimations) { runningAnimations = runningAnimationsMap[elementId] = {}; } runningAnimations[animationId] = animation; names = []; durations = []; easings = []; delays = []; directions = []; iterations = []; for (name in runningAnimations) { if (runningAnimations.hasOwnProperty(name)) { runningAnimation = runningAnimations[name]; names.push(name); durations.push(runningAnimation.duration); easings.push(runningAnimation.easing); delays.push(runningAnimation.delay); directions.push(runningAnimation.direction); iterations.push(runningAnimation.iteration); } } data[elementId] = { 'animation-name': names, 'animation-duration': durations, 'animation-timing-function': easings, 'animation-delay': delays, 'animation-direction': directions, 'animation-iteration-count': iterations }; if (animation.preserveEndState) { elementEndStates[elementId] = states['100%']; } } this.applyStyles(data); }, addKeyframesRule: function(name, keyframes) { var percentage, properties, keyframesRule, styleSheet, rules, styles, rulesLength, key, value; styleSheet = this.getStyleSheet(); rules = styleSheet.cssRules; rulesLength = rules.length; styleSheet.insertRule('@' + this.vendorPrefix + 'keyframes ' + name + '{}', rulesLength); keyframesRule = rules[rulesLength]; for (percentage in keyframes) { properties = keyframes[percentage]; rules = keyframesRule.cssRules; rulesLength = rules.length; styles = []; for (key in properties) { value = this.formatValue(properties[key], key); key = this.formatName(key); styles.push(key + ':' + value); } keyframesRule.insertRule(percentage + '{' + styles.join(';') + '}', rulesLength); } return this; }, removeKeyframesRule: function(name) { var styleSheet = this.getStyleSheet(), rules = styleSheet.cssRules, i, ln, rule; for (i = 0 , ln = rules.length; i < ln; i++) { rule = rules[i]; if (rule.name === name) { styleSheet.removeRule(i); break; } } return this; } }); Ext.define('Ext.mixin.Hookable', { extend: 'Ext.Mixin', mixinConfig: { id: 'hookable' }, bind: function(instance, boundMethod, bindingMethod, preventDefault, extraArgs) { if (!bindingMethod) { bindingMethod = boundMethod; } var boundFn = instance[boundMethod], fn, binding; if (boundFn && boundFn.hasOwnProperty('$binding')) { binding = boundFn.$binding; if (binding.bindingMethod === bindingMethod && binding.bindingScope === this) { return this; } } instance[boundMethod] = fn = function() { var binding = fn.$binding, scope = binding.bindingScope, args = Array.prototype.slice.call(arguments); args.push(arguments); if (extraArgs) { args.push.apply(args, extraArgs); } if (!binding.preventDefault && scope[binding.bindingMethod].apply(scope, args) !== false) { return binding.boundFn.apply(this, arguments); } }; fn.$binding = { preventDefault: !!preventDefault, boundFn: boundFn, bindingMethod: bindingMethod, bindingScope: this }; return this; }, unbind: function(instance, boundMethod, bindingMethod) { if (!bindingMethod) { bindingMethod = boundMethod; } var fn = instance[boundMethod], binding = fn.$binding, boundFn, currentBinding; while (binding) { boundFn = binding.boundFn; if (binding.bindingMethod === bindingMethod && binding.bindingScope === this) { if (currentBinding) { currentBinding.boundFn = boundFn; } else { instance[boundMethod] = boundFn; } return this; } currentBinding = binding; binding = boundFn.$binding; } return this; } }); Ext.define('Ext.mixin.Mashup', function(Mashup) { return { extend: 'Ext.Mixin', mixinConfig: { id: 'mashup', extended: function(baseClass, derivedClass) { Mashup.process(derivedClass); } }, statics: { process: function(targetClass) { var body = targetClass.prototype, requiredScripts = body.requiredScripts, hooks = targetClass._classHooks, onCreated = hooks.onCreated; if (requiredScripts) { delete body.requiredScripts; hooks.onCreated = function() { var me = this, args = Ext.Array.slice(arguments); Ext.Loader.loadScripts({ url: requiredScripts, cache: true, onLoad: function() { hooks.onCreated = onCreated; hooks.onCreated.call(me, args); } }); }; } } }, onClassMixedIn: function(targetClass) { Mashup.process(targetClass); } }; }); Ext.define('Ext.mixin.Responsive', function(Responsive) { return { extend: 'Ext.Mixin', requires: [ 'Ext.GlobalEvents' ], mixinConfig: { id: 'responsive', after: { destroy: 'destroy' } }, config: { responsiveConfig: { $value: undefined, merge: function(newValue, oldValue, target, mixinClass) { if (!newValue) { return oldValue; } var ret = oldValue ? Ext.Object.chain(oldValue) : {}, rule; for (rule in newValue) { if (!mixinClass || !(rule in ret)) { ret[rule] = { fn: null, config: newValue[rule] }; } } return ret; } }, responsiveFormulas: { $value: 0, merge: function(newValue, oldValue, target, mixinClass) { return this.mergeNew(newValue, oldValue, target, mixinClass); } } }, destroy: function() { Responsive.unregister(this); this.callParent(); }, privates: { statics: { active: false, all: {}, context: Ext.Object.chain(Ext.platformTags), count: 0, nextId: 0, activate: function() { Responsive.active = true; Responsive.updateContext(); Ext.on('resize', Responsive.onResize, Responsive); }, deactivate: function() { Responsive.active = false; Ext.un('resize', Responsive.onResize, Responsive); }, notify: function() { var all = Responsive.all, context = Responsive.context, globalEvents = Ext.GlobalEvents, timer = Responsive.timer, id; if (timer) { Responsive.timer = null; Ext.Function.cancelAnimationFrame(timer); } Responsive.updateContext(); Ext.suspendLayouts(); globalEvents.fireEvent('beforeresponsiveupdate', context); for (id in all) { all[id].setupResponsiveContext(); } globalEvents.fireEvent('beginresponsiveupdate', context); for (id in all) { all[id].updateResponsiveState(); } globalEvents.fireEvent('responsiveupdate', context); Ext.resumeLayouts(true); }, onResize: function() { if (!Responsive.timer) { Responsive.timer = Ext.Function.requestAnimationFrame(Responsive.onTimer); } }, onTimer: function() { Responsive.timer = null; Responsive.notify(); }, processConfig: function(instance, instanceConfig, name) { var value = instanceConfig && instanceConfig[name], config = instance.config, cfg, configurator; if (value) { configurator = instance.getConfigurator(); cfg = configurator.configs[name]; config[name] = cfg.merge(value, config[name], instance); } }, register: function(responder) { var id = responder.$responsiveId; if (!id) { responder.$responsiveId = id = ++Responsive.nextId; Responsive.all[id] = responder; if (++Responsive.count === 1) { Responsive.activate(); } } }, unregister: function(responder) { var id = responder.$responsiveId; if (id in Responsive.all) { responder.$responsiveId = null; delete Responsive.all[id]; if (--Responsive.count === 0) { Responsive.deactivate(); } } }, updateContext: function() { var El = Ext.Element, width = El.getViewportWidth(), height = El.getViewportHeight(), context = Responsive.context; context.width = width; context.height = height; context.tall = width < height; context.wide = !context.tall; context.landscape = context.portrait = false; if (!context.platform) { context.platform = Ext.platformTags; } context[Ext.dom.Element.getOrientation()] = true; } }, afterClassMixedIn: function(targetClass) { var proto = targetClass.prototype, responsiveConfig = proto.responsiveConfig, responsiveFormulas = proto.responsiveFormulas, config; if (responsiveConfig || responsiveFormulas) { config = {}; if (responsiveConfig) { delete proto.responsiveConfig; config.responsiveConfig = responsiveConfig; } if (responsiveFormulas) { delete proto.responsiveFormulas; config.responsiveFormulas = responsiveFormulas; } targetClass.getConfigurator().add(config); } }, applyResponsiveConfig: function(rules) { for (var rule in rules) { rules[rule].fn = Ext.createRuleFn(rule); } return rules; }, applyResponsiveFormulas: function(formulas) { var ret = {}, fn, name; if (formulas) { for (name in formulas) { if (Ext.isString(fn = formulas[name])) { fn = Ext.createRuleFn(fn); } ret[name] = fn; } } return ret; }, getResponsiveState: function() { var context = Responsive.context, rules = this.getResponsiveConfig(), ret = {}, entry, rule; if (rules) { for (rule in rules) { entry = rules[rule]; if (entry.fn.call(this, context)) { Ext.merge(ret, entry.config); } } } return ret; }, setupResponsiveContext: function() { var formulas = this.getResponsiveFormulas(), context = Responsive.context, name; if (formulas) { for (name in formulas) { context[name] = formulas[name].call(this, context); } } }, transformInstanceConfig: function(instanceConfig) { var me = this, ret; Responsive.register(me); if (instanceConfig) { Responsive.processConfig(me, instanceConfig, 'responsiveConfig'); Responsive.processConfig(me, instanceConfig, 'responsiveFormulas'); } me.setupResponsiveContext(); ret = me.getResponsiveState(); if (instanceConfig) { ret = Ext.merge({}, instanceConfig, ret); delete ret.responsiveConfig; delete ret.responsiveFormulas; } return ret; }, updateResponsiveState: function() { var config = this.getResponsiveState(); this.setConfig(config); } } }; }); Ext.define('Ext.mixin.Selectable', { extend: 'Ext.Mixin', mixinConfig: { id: 'selectable', after: { updateStore: 'updateStore' } }, config: { disableSelection: null, mode: 'SINGLE', allowDeselect: false, lastSelected: null, lastFocused: null, deselectOnContainerClick: true }, modes: { SINGLE: true, SIMPLE: true, MULTI: true }, selectableEventHooks: { addrecords: 'onSelectionStoreAdd', removerecords: 'onSelectionStoreRemove', updaterecord: 'onSelectionStoreUpdate', load: 'refreshSelection', refresh: 'refreshSelection' }, constructor: function() { this.selected = new Ext.util.MixedCollection(); this.callParent(arguments); }, applyMode: function(mode) { mode = mode ? mode.toUpperCase() : 'SINGLE'; return this.modes[mode] ? mode : 'SINGLE'; }, updateStore: function(newStore, oldStore) { var me = this, bindEvents = Ext.apply({}, me.selectableEventHooks, { scope: me }); if (oldStore && Ext.isObject(oldStore) && oldStore.isStore) { if (oldStore.autoDestroy) { oldStore.destroy(); } else { oldStore.un(bindEvents); if (newStore) { newStore.un('clear', 'onSelectionStoreClear', this); } } } if (newStore) { newStore.on(bindEvents); newStore.onBefore('clear', 'onSelectionStoreClear', this); me.refreshSelection(); } }, selectAll: function(silent) { var me = this, selections = me.getStore().getRange(); me.select(selections, true, silent); }, deselectAll: function(supress) { var me = this, selections = me.getStore().getRange(); me.deselect(selections, supress); me.selected.clear(); me.setLastSelected(null); me.setLastFocused(null); }, selectWithEvent: function(record) { var me = this, isSelected = me.isSelected(record); switch (me.getMode()) { case 'MULTI': case 'SIMPLE': if (isSelected) { me.deselect(record); } else { me.select(record, true); }; break; case 'SINGLE': if (me.getAllowDeselect() && isSelected) { me.deselect(record); } else { me.select(record, false); }; break; } }, selectRange: function(startRecord, endRecord, keepExisting) { var me = this, store = me.getStore(), records = [], tmp, i; if (me.getDisableSelection()) { return; } if (startRecord > endRecord) { tmp = endRecord; endRecord = startRecord; startRecord = tmp; } for (i = startRecord; i <= endRecord; i++) { records.push(store.getAt(i)); } this.doMultiSelect(records, keepExisting); }, select: function(records, keepExisting, suppressEvent) { var me = this, record; if (me.getDisableSelection()) { return; } if (typeof records === "number") { records = [ me.getStore().getAt(records) ]; } if (!records) { return; } if (me.getMode() == "SINGLE" && records) { record = records.length ? records[0] : records; me.doSingleSelect(record, suppressEvent); } else { me.doMultiSelect(records, keepExisting, suppressEvent); } }, doSingleSelect: function(record, suppressEvent) { var me = this, selected = me.selected; if (me.getDisableSelection()) { return; } if (me.isSelected(record)) { return; } if (selected.getCount() > 0) { me.deselect(me.getLastSelected(), suppressEvent); } selected.add(record); me.setLastSelected(record); me.onItemSelect(record, suppressEvent); me.setLastFocused(record); if (!suppressEvent) { me.fireSelectionChange([ record ]); } }, doMultiSelect: function(records, keepExisting, suppressEvent) { if (records === null || this.getDisableSelection()) { return; } records = !Ext.isArray(records) ? [ records ] : records; var me = this, selected = me.selected, ln = records.length, change = false, i = 0, record; if (!keepExisting && selected.getCount() > 0) { change = true; me.deselect(me.getSelection(), true); } for (; i < ln; i++) { record = records[i]; if (keepExisting && me.isSelected(record)) { continue; } change = true; me.setLastSelected(record); selected.add(record); if (!suppressEvent) { me.setLastFocused(record); } me.onItemSelect(record, suppressEvent); } if (change && !suppressEvent) { this.fireSelectionChange(records); } }, deselect: function(records, suppressEvent) { var me = this; if (me.getDisableSelection()) { return; } records = Ext.isArray(records) ? records : [ records ]; var selected = me.selected, change = false, i = 0, store = me.getStore(), ln = records.length, record; for (; i < ln; i++) { record = records[i]; if (typeof record === 'number') { record = store.getAt(record); } if (selected.remove(record)) { if (me.getLastSelected() == record) { me.setLastSelected(selected.last()); } change = true; } if (record) { me.onItemDeselect(record, suppressEvent); } } if (change && !suppressEvent) { me.fireSelectionChange(records); } }, updateLastFocused: function(newRecord, oldRecord) { this.onLastFocusChanged(oldRecord, newRecord); }, fireSelectionChange: function(records) { var me = this; me.fireAction('beforeselectionchange', [ me ], function() { me.fireAction('selectionchange', [ me, records ], 'getSelection'); }); }, getSelection: function() { return this.selected.getRange(); }, isSelected: function(record) { record = Ext.isNumber(record) ? this.getStore().getAt(record) : record; return this.selected.indexOf(record) !== -1; }, hasSelection: function() { return this.selected.getCount() > 0; }, refreshSelection: function() { var me = this, selections = me.getSelection(); me.deselectAll(true); if (selections.length) { me.select(selections, false, true); } }, onSelectionStoreRemove: function(store, records) { var me = this, selected = me.selected, ln = records.length, record, i; if (me.getDisableSelection()) { return; } for (i = 0; i < ln; i++) { record = records[i]; if (selected.remove(record)) { if (me.getLastSelected() == record) { me.setLastSelected(null); } if (me.getLastFocused() == record) { me.setLastFocused(null); } me.fireSelectionChange([ record ]); } } }, onSelectionStoreClear: function(store) { var records = store.getData().items; this.onSelectionStoreRemove(store, records); }, getSelectionCount: function() { return this.selected.getCount(); }, onSelectionStoreAdd: Ext.emptyFn, onSelectionStoreUpdate: Ext.emptyFn, onItemSelect: Ext.emptyFn, onItemDeselect: Ext.emptyFn, onLastFocusChanged: Ext.emptyFn, onEditorKey: Ext.emptyFn }, function() {}); Ext.define('Ext.mixin.Traversable', { extend: 'Ext.Mixin', mixinConfig: { id: 'traversable' }, setParent: function(parent) { this.parent = parent; return this; }, hasParent: function() { return Boolean(this.parent); }, getParent: function() { return this.parent; }, getAncestors: function() { var ancestors = [], parent = this.getParent(); while (parent) { ancestors.push(parent); parent = parent.getParent(); } return ancestors; }, getAncestorIds: function() { var ancestorIds = [], parent = this.getParent(); while (parent) { ancestorIds.push(parent.getId()); parent = parent.getParent(); } return ancestorIds; } }); Ext.define('Ext.perf.Accumulator', function() { var currentFrame = null, khrome = Ext.global['chrome'], formatTpl, getTimestamp = function() { getTimestamp = Ext.now; var interval, toolbox; if (Ext.isChrome && khrome && khrome.Interval) { interval = new khrome.Interval(); interval.start(); getTimestamp = function() { return interval.microseconds() / 1000; }; } else if (window.ActiveXObject) { try { toolbox = new ActiveXObject('SenchaToolbox.Toolbox'); Ext.senchaToolbox = toolbox; getTimestamp = function() { return toolbox.milliseconds; }; } catch (e) {} } Ext.perf.getTimestamp = Ext.perf.Accumulator.getTimestamp = getTimestamp; return getTimestamp(); }; function adjustSet(set, time) { set.sum += time; set.min = Math.min(set.min, time); set.max = Math.max(set.max, time); } function leaveFrame(time) { var totalTime = time ? time : (getTimestamp() - this.time), me = this, accum = me.accum; ++accum.count; if (!--accum.depth) { adjustSet(accum.total, totalTime); } adjustSet(accum.pure, totalTime - me.childTime); currentFrame = me.parent; if (currentFrame) { ++currentFrame.accum.childCount; currentFrame.childTime += totalTime; } } function makeSet() { return { min: Number.MAX_VALUE, max: 0, sum: 0 }; } function makeTap(me, fn) { return function() { var frame = me.enter(), ret = fn.apply(this, arguments); frame.leave(); return ret; }; } function setToJSON(count, childCount, calibration, set) { var data = { avg: 0, min: set.min, max: set.max, sum: 0 }; if (count) { calibration = calibration || 0; data.sum = set.sum - childCount * calibration; data.avg = data.sum / count; } return data; } return { requires: [ 'Ext.XTemplate', 'Ext.ClassManager' ], constructor: function(name) { var me = this; me.count = me.childCount = me.depth = me.maxDepth = 0; me.pure = makeSet(); me.total = makeSet(); me.name = name; }, statics: { getTimestamp: getTimestamp }, format: function(calibration) { if (!formatTpl) { formatTpl = new Ext.XTemplate([ '{name} - {count} call(s)', '', '', ' ({childCount} children)', '', '', ' ({depth} deep)', '', '', ', {type}: {[this.time(values.sum)]} msec (', 'avg={[this.time(values.sum / parent.count)]}', ')', '', '' ].join(''), { time: function(t) { return Math.round(t * 100) / 100; } }); } var data = this.getData(calibration); data.name = this.name; data.pure.type = 'Pure'; data.total.type = 'Total'; data.times = [ data.pure, data.total ]; return formatTpl.apply(data); }, getData: function(calibration) { var me = this; return { count: me.count, childCount: me.childCount, depth: me.maxDepth, pure: setToJSON(me.count, me.childCount, calibration, me.pure), total: setToJSON(me.count, me.childCount, calibration, me.total) }; }, enter: function() { var me = this, frame = { accum: me, leave: leaveFrame, childTime: 0, parent: currentFrame }; ++me.depth; if (me.maxDepth < me.depth) { me.maxDepth = me.depth; } currentFrame = frame; frame.time = getTimestamp(); return frame; }, monitor: function(fn, scope, args) { var frame = this.enter(); if (args) { fn.apply(scope, args); } else { fn.call(scope); } frame.leave(); }, report: function() { Ext.log(this.format()); }, tap: function(className, methodName) { var me = this, methods = typeof methodName === 'string' ? [ methodName ] : methodName, klass, statik, i, parts, length, name, src, tapFunc; tapFunc = function() { if (typeof className === 'string') { klass = Ext.global; parts = className.split('.'); for (i = 0 , length = parts.length; i < length; ++i) { klass = klass[parts[i]]; } } else { klass = className; } for (i = 0 , length = methods.length; i < length; ++i) { name = methods[i]; statik = name.charAt(0) === '!'; if (statik) { name = name.substring(1); } else { statik = !(name in klass.prototype); } src = statik ? klass : klass.prototype; src[name] = makeTap(me, src[name]); } }; Ext.ClassManager.onCreated(tapFunc, me, className); return me; } }; }, function() { Ext.perf.getTimestamp = this.getTimestamp; }); Ext.define('Ext.perf.Monitor', { singleton: true, alternateClassName: 'Ext.Perf', requires: [ 'Ext.perf.Accumulator' ], constructor: function() { this.accumulators = []; this.accumulatorsByName = {}; }, calibrate: function() { var accum = new Ext.perf.Accumulator('$'), total = accum.total, getTimestamp = Ext.perf.Accumulator.getTimestamp, count = 0, frame, endTime, startTime; startTime = getTimestamp(); do { frame = accum.enter(); frame.leave(); ++count; } while (total.sum < 100); endTime = getTimestamp(); return (endTime - startTime) / count; }, get: function(name) { var me = this, accum = me.accumulatorsByName[name]; if (!accum) { me.accumulatorsByName[name] = accum = new Ext.perf.Accumulator(name); me.accumulators.push(accum); } return accum; }, enter: function(name) { return this.get(name).enter(); }, monitor: function(name, fn, scope) { this.get(name).monitor(fn, scope); }, report: function() { var me = this, accumulators = me.accumulators, calibration = me.calibrate(); accumulators.sort(function(a, b) { return (a.name < b.name) ? -1 : ((b.name < a.name) ? 1 : 0); }); me.updateGC(); Ext.log('Calibration: ' + Math.round(calibration * 100) / 100 + ' msec/sample'); Ext.each(accumulators, function(accum) { Ext.log(accum.format(calibration)); }); }, getData: function(all) { var ret = {}, accumulators = this.accumulators; Ext.each(accumulators, function(accum) { if (all || accum.count) { ret[accum.name] = accum.getData(); } }); return ret; }, reset: function() { Ext.each(this.accumulators, function(accum) { var me = accum; me.count = me.childCount = me.depth = me.maxDepth = 0; me.pure = { min: Number.MAX_VALUE, max: 0, sum: 0 }; me.total = { min: Number.MAX_VALUE, max: 0, sum: 0 }; }); }, updateGC: function() { var accumGC = this.accumulatorsByName.GC, toolbox = Ext.senchaToolbox, bucket; if (accumGC) { accumGC.count = toolbox.garbageCollectionCounter || 0; if (accumGC.count) { bucket = accumGC.pure; accumGC.total.sum = bucket.sum = toolbox.garbageCollectionMilliseconds; bucket.min = bucket.max = bucket.sum / accumGC.count; bucket = accumGC.total; bucket.min = bucket.max = bucket.sum / accumGC.count; } } }, watchGC: function() { Ext.perf.getTimestamp(); var toolbox = Ext.senchaToolbox; if (toolbox) { this.get("GC"); toolbox.watchGarbageCollector(false); } }, setup: function(config) { if (!config) { config = { render: { 'Ext.Component': 'render' }, layout: { 'Ext.layout.Context': 'run' } }; } this.currentConfig = config; var key, prop, accum, className, methods; for (key in config) { if (config.hasOwnProperty(key)) { prop = config[key]; accum = Ext.Perf.get(key); for (className in prop) { if (prop.hasOwnProperty(className)) { methods = prop[className]; accum.tap(className, methods); } } } } this.watchGC(); } }); Ext.define('Ext.plugin.Abstract', { alternateClassName: 'Ext.AbstractPlugin', isPlugin: true, constructor: function(config) { if (config) { this.pluginConfig = config; this.initConfig(config); } }, clonePlugin: function(overrideCfg) { return new this.self(Ext.apply({}, overrideCfg, this.pluginConfig)); }, setCmp: function(cmp) { this.cmp = cmp; }, getCmp: function() { return this.cmp; }, init: Ext.emptyFn, onClassExtended: function(cls, data, hooks) { var alias = data.alias; if (alias && !data.ptype) { if (Ext.isArray(alias)) { alias = alias[0]; } cls.prototype.ptype = alias.split('plugin.')[1]; } }, resolveListenerScope: function(defaultScope) { var me = this, cmp = me.getCmp(), scope; if (cmp) { scope = cmp.resolveSatelliteListenerScope(me, defaultScope); } return scope || me.mixins.observable.resolveListenerScope.call(me, defaultScope); } }); Ext.define('Ext.overrides.plugin.Abstract', { override: 'Ext.plugin.Abstract', $configStrict: false, $configPrefixed: false, disabled: false, getState: null, applyState: null, enable: function() { this.disabled = false; }, disable: function() { this.disabled = true; } }); Ext.define('Ext.plugin.LazyItems', { extend: 'Ext.plugin.Abstract', alias: 'plugin.lazyitems', init: function(comp) { this.callParent(arguments); if (this.items) { if (this.eagerInstantiation) { this.items = comp.prepareItems(this.items); } } comp.beforeRender = Ext.Function.createInterceptor(comp.beforeRender, this.beforeComponentRender, this); }, beforeComponentRender: function() { this.cmp.add(this.items); delete this.cmp.beforeComponentRender; } }); Ext.define('Ext.util.Base64', { singleton: true, _str: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", encode: function(input) { var me = this; var output = '', chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0; input = me._utf8_encode(input); var len = input.length; while (i < len) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + me._str.charAt(enc1) + me._str.charAt(enc2) + me._str.charAt(enc3) + me._str.charAt(enc4); } return output; }, decode: function(input) { var me = this; var output = '', chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); var len = input.length; while (i < len) { enc1 = me._str.indexOf(input.charAt(i++)); enc2 = me._str.indexOf(input.charAt(i++)); enc3 = me._str.indexOf(input.charAt(i++)); enc4 = me._str.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 !== 64) { output = output + String.fromCharCode(chr2); } if (enc4 !== 64) { output = output + String.fromCharCode(chr3); } } output = me._utf8_decode(output); return output; }, _utf8_encode: function(string) { string = string.replace(/\r\n/g, "\n"); var utftext = '', n = 0, len = string.length; for (; n < len; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if ((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } return utftext; }, _utf8_decode: function(utftext) { var string = '', i = 0, c = 0, c3 = 0, c2 = 0, len = utftext.length; while (i < len) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if ((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i + 1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } }); Ext.define('Ext.util.DelimitedValue', { dateFormat: 'C', delimiter: '\t', lineBreak: '\n', quote: '"', parseREs: {}, quoteREs: {}, lineBreakRe: /\r?\n/g, constructor: function(config) { if (config) { Ext.apply(this, config); } }, decode: function(input, delimiter) { var me = this, delim = (delimiter || me.delimiter), row = [], result = [ row ], quote = me.quote, quoteREs = me.quoteREs, parseREs = me.parseREs, parseRE = parseREs[delim] || (parseREs[delim] = new RegExp( "(\\" + delim + "|\\r?\\n|\\r|^)" + "(?:\\" + quote + "([^\\" + quote + "]*(?:\\" + quote + "\\" + quote + "[^\\" + quote + "]*)*)\\" + quote + "|" + "([^\"\\" + delim + "\\r\\n]*))", "gi")), dblQuoteRE = quoteREs[quote] || (quoteREs[quote] = new RegExp('\\' + quote + '\\' + quote, 'g')), arrMatches, strMatchedDelimiter, strMatchedValue; while (arrMatches = parseRE.exec(input)) { strMatchedDelimiter = arrMatches[1]; if (strMatchedDelimiter.length && strMatchedDelimiter !== delim) { result.push(row = []); } if (arrMatches[2]) { strMatchedValue = arrMatches[2].replace(dblQuoteRE, '"'); } else { strMatchedValue = arrMatches[3]; } row.push(strMatchedValue); } return result; }, encode: function(input, delimiter) { var me = this, delim = delimiter || me.delimiter, dateFormat = me.dateFormat, quote = me.quote, twoQuotes = quote + quote, rowIndex = input.length, lineBreakRe = me.lineBreakRe, result = [], outputRow = [], col, columnIndex, inputRow; while (rowIndex-- > 0) { inputRow = input[rowIndex]; outputRow.length = columnIndex = inputRow.length; while (columnIndex-- > 0) { col = inputRow[columnIndex]; if (col == null) { col = ''; } else if (typeof col === 'string') { if (col) { if (col.indexOf(quote) > -1) { col = quote + col.split(quote).join(twoQuotes) + quote; } else if (col.indexOf(delim) > -1 || lineBreakRe.test(col)) { col = quote + col + quote; } } } else if (Ext.isDate(col)) { col = Ext.Date.format(col, dateFormat); } else if (col && (isNaN(col) || Ext.isArray(col))) { Ext.Error.raise('Cannot serialize ' + Ext.typeOf(col) + ' into CSV'); } outputRow[columnIndex] = col; } result[rowIndex] = outputRow.join(delim); } return result.join(me.lineBreak); } }); Ext.define('Ext.util.CSV', { extend: 'Ext.util.DelimitedValue', singleton: true, delimiter: ',' }); Ext.define('Ext.util.LocalStorage', { id: null, destroyed: false, lazyKeys: true, prefix: '', session: false, _keys: null, _store: null, _users: 0, statics: { cache: {}, get: function(id) { var me = this, cache = me.cache, config = { _users: 1 }, instance; if (Ext.isString(id)) { config.id = id; } else { Ext.apply(config, id); } if (!(instance = cache[config.id])) { instance = new me(config); } else { if (instance === true) { Ext.Error.raise('Creating a shared instance of private local store "' + me.id + '".'); } ++instance._users; } return instance; }, supported: true }, constructor: function(config) { var me = this; Ext.apply(me, config); if (!me.hasOwnProperty('id')) { Ext.Error.raise("No id was provided to the local store."); } if (me._users) { Ext.util.LocalStorage.cache[me.id] = me; } else { if (Ext.util.LocalStorage.cache[me.id]) { Ext.Error.raise('Cannot create duplicate instance of local store "' + me.id + '". Use Ext.util.LocalStorage.get() to share instances.'); } Ext.util.LocalStorage.cache[me.id] = true; } me.init(); }, init: function() { var me = this, id = me.id; if (!me.prefix && id) { me.prefix = id + '-'; } me._store = (me.session ? window.sessionStorage : window.localStorage); }, destroy: function() { var me = this; if (me._users) { Ext.log.warn('LocalStorage(id=' + me.id + ') destroyed while in use'); } delete Ext.util.LocalStorage.cache[me.id]; me._store = me._keys = null; me.destroyed = true; me.destroy = Ext.emptyFn; }, getKeys: function() { var me = this, store = me._store, prefix = me.prefix, keys = me._keys, n = prefix.length, i, key; if (!keys) { me._keys = keys = []; for (i = store.length; i--; ) { key = store.key(i); if (key.length > n) { if (prefix === key.substring(0, n)) { keys.push(key.substring(n)); } } } } return keys; }, release: function() { if (!--this._users) { this.destroy(); } }, save: Ext.emptyFn, clear: function() { var me = this, store = me._store, prefix = me.prefix, keys = me._keys || me.getKeys(), i; for (i = keys.length; i--; ) { store.removeItem(prefix + keys[i]); } keys.length = 0; }, key: function(index) { var keys = this._keys || this.getKeys(); return (0 <= index && index < keys.length) ? keys[index] : null; }, getItem: function(key) { var k = this.prefix + key; return this._store.getItem(k); }, removeItem: function(key) { var me = this, k = me.prefix + key, store = me._store, keys = me._keys, length = store.length; store.removeItem(k); if (keys && length !== store.length) { if (me.lazyKeys) { me._keys = null; } else { Ext.Array.remove(keys, key); } } }, setItem: function(key, value) { var me = this, k = me.prefix + key, store = me._store, length = store.length, keys = me._keys; store.setItem(k, value); if (keys && length !== store.length) { keys.push(key); } } }, function() { var LocalStorage = this; if ('localStorage' in window) { return; } if (!Ext.isIE) { LocalStorage.supported = false; LocalStorage.prototype.init = function() { Ext.Error.raise("Local storage is not supported on this browser"); }; return; } LocalStorage.override({ data: null, flushDelay: 1, init: function() { var me = this, data = me.data, el; me.el = el = document.createElement('div'); el.id = (me.id || (me.id = 'extjs-localstore')); el.addBehavior('#default#userdata'); Ext.getHead().dom.appendChild(el); el.load(me.id); data = el.getAttribute('xdata'); me.data = data = (data ? Ext.decode(data) : {}); me._flushFn = function() { me._timer = null; me.save(0); }; }, destroy: function() { var me = this, el = me.el; if (el) { if (me._timer) { me.save(); } el.parentNode.removeChild(el); me.data = me.el = null; me.callParent(); } }, getKeys: function() { var me = this, keys = me._keys; if (!keys) { me._keys = keys = Ext.Object.getKeys(me.data); } return keys; }, save: function(delay) { var me = this; if (!delay) { if (me._timer) { clearTimeout(me._timer); me._timer = null; } me.el.setAttribute('xdata', Ext.encode(me.data)); me.el.save(me.id); } else if (!me._timer) { me._timer = Ext.defer(me._flushFn, delay); } }, clear: function() { var me = this; me.data = {}; me._keys = null; me.save(me.flushDelay); }, getItem: function(key) { var data = this.data; return (key in data) ? data[key] : null; }, removeItem: function(key) { var me = this, keys = me._keys, data = me.data; if (key in data) { delete data[key]; if (keys) { if (me.lazyKeys) { me._keys = null; } else { Ext.Array.remove(keys, key); } } me.save(me.flushDelay); } }, setItem: function(key, value) { var me = this, data = me.data, keys = me._keys; if (keys && !(key in data)) { keys.push(key); } data[key] = value; me.save(me.flushDelay); } }); }); Ext.define('Ext.util.TSV', { extend: 'Ext.util.DelimitedValue', singleton: true, delimiter: '\t' }); Ext.define('Ext.util.TaskManager', { extend: 'Ext.util.TaskRunner', alternateClassName: [ 'Ext.TaskManager' ], singleton: true }); Ext.define('Ext.util.TextMetrics', { requires: [ 'Ext.dom.Element' ], 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 me = this, measure = Ext.getBody().createChild({ 'data-sticky': true, role: 'presentation', cls: Ext.baseCSSPrefix + 'textmetrics' }); me.measure = measure; if (bindTo) { me.bind(bindTo); } measure.position('absolute'); measure.setLocalXY(-1000, -1000); measure.hide(); if (fixedWidth) { measure.setWidth(fixedWidth); } }, getSize: function(text) { var measure = this.measure, size; measure.setHtml(text); size = measure.getSize(); measure.setHtml(''); return size; }, bind: function(el) { var me = this; me.el = Ext.get(el); me.measure.setStyle(me.el.getStyle([ 'font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing', 'word-break' ])); }, 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.destroy(); delete me.el; delete me.measure; } }, function() { Ext.Element.override({ getTextWidth: function(text, min, max) { return Ext.Number.constrain(Ext.util.TextMetrics.measure(this.dom, Ext.valueFrom(text, this.dom.innerHTML, true)).width, min || 0, max || 1000000); } }); }); Ext.define('Ext.Action', { constructor: function(config) { this.initialConfig = config; this.itemId = config.itemId = (config.itemId || config.id || Ext.id()); this.items = []; }, isAction: true, setText: function(text) { this.initialConfig.text = text; this.callEach('setText', [ text ]); }, getText: function() { return this.initialConfig.text; }, setIconCls: function(cls) { this.initialConfig.iconCls = cls; this.callEach('setIconCls', [ cls ]); }, getIconCls: function() { return this.initialConfig.iconCls; }, setDisabled: function(v) { this.initialConfig.disabled = v; this.callEach('setDisabled', [ v ]); }, enable: function() { this.setDisabled(false); }, disable: function() { this.setDisabled(true); }, isDisabled: function() { return this.initialConfig.disabled; }, setHidden: function(v) { this.initialConfig.hidden = v; this.callEach('setVisible', [ !v ]); }, show: function() { this.setHidden(false); }, hide: function() { this.setHidden(true); }, isHidden: function() { return this.initialConfig.hidden; }, setHandler: function(fn, scope) { this.initialConfig.handler = fn; this.initialConfig.scope = scope; this.callEach('setHandler', [ fn, scope ]); }, each: function(fn, scope) { Ext.each(this.items, fn, scope); }, callEach: function(fnName, args) { var items = this.items, i = 0, len = items.length, item; Ext.suspendLayouts(); for (; i < len; i++) { item = items[i]; item[fnName].apply(item, args); } Ext.resumeLayouts(true); }, addComponent: function(comp) { this.items.push(comp); comp.on('destroy', this.removeComponent, this); }, removeComponent: function(comp) { Ext.Array.remove(this.items, comp); }, execute: function() { this.initialConfig.handler.apply(this.initialConfig.scope || Ext.global, arguments); } }); Ext.define('Ext.ElementLoader', { mixins: { observable: 'Ext.util.Observable' }, uses: [ 'Ext.data.Connection', 'Ext.Ajax' ], statics: { Renderer: { Html: function(loader, response, active) { loader.getTarget().setHtml(response.responseText, active.scripts === true); return true; } } }, url: null, params: null, baseParams: null, autoLoad: false, target: null, loadMask: false, ajaxOptions: null, scripts: false, isLoader: true, constructor: function(config) { var me = this, autoLoad; config = config || {}; Ext.apply(me, config); me.mixins.observable.constructor.call(me); me.setTarget(me.target); if (me.autoLoad) { autoLoad = me.autoLoad; if (autoLoad === true) { autoLoad = null; } me.load(autoLoad); } }, setTarget: function(target) { var me = this; target = Ext.get(target); if (me.target && me.target !== target) { me.abort(); } me.target = target; }, getTarget: function() { return this.target || null; }, abort: function() { var active = this.active; if (active !== undefined) { Ext.Ajax.abort(active.request); if (active.mask) { this.removeMask(); } delete this.active; } }, removeMask: function() { this.target.unmask(); }, addMask: function(mask) { this.target.mask(mask === true ? null : mask); }, load: function(options) { if (!this.target) { Ext.Error.raise('A valid target is required when loading content'); } options = Ext.apply({}, options); var me = this, 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, rendererScope = options.rendererScope || me.rendererScope || me; 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); } me.active = { options: options, mask: mask, scope: scope, rendererScope: rendererScope, 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.active.request = Ext.Ajax.request(options); me.setOptions(me.active, options); }, setOptions: Ext.emptyFn, onComplete: function(options, success, response) { var me = this, active = me.active, rendererScope, scope; if (active) { scope = active.scope; rendererScope = active.rendererScope; if (success) { success = me.getRenderer(active.renderer).call(rendererScope, me, response, active) !== false; } if (success) { Ext.callback(active.success, scope, [ me, response, options ]); me.fireEvent('load', me, response, options); } else { Ext.callback(active.failure, scope, [ me, response, options ]); me.fireEvent('exception', me, response, options); } Ext.callback(active.callback, scope, [ me, success, response, options ]); if (active.mask) { me.removeMask(); } } delete me.active; }, getRenderer: function(renderer) { if (Ext.isFunction(renderer)) { return renderer; } return this.statics().Renderer.Html; }, startAutoRefresh: function(interval, options) { var me = this; me.stopAutoRefresh(); me.autoRefresh = Ext.interval(function() { me.load(options); }, interval); }, stopAutoRefresh: function() { clearInterval(this.autoRefresh); delete this.autoRefresh; }, isAutoRefreshing: function() { return Ext.isDefined(this.autoRefresh); }, destroy: function() { var me = this; me.stopAutoRefresh(); delete me.target; me.abort(); me.clearListeners(); } }); Ext.define('Ext.ComponentLoader', { extend: 'Ext.ElementLoader', statics: { Renderer: { Data: function(loader, response, active) { var success = true; try { loader.getTarget().update(Ext.decode(response.responseText)); } catch (e) { success = false; } return success; }, Component: function(loader, response, active) { var success = true, target = loader.getTarget(), items = []; 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) { target.suspendLayouts(); if (active.removeAll) { target.removeAll(); } target.add(items); target.resumeLayouts(true); } return success; } } }, target: null, loadOnRender: false, 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; if (target && me.loadOnRender) { if (target.rendered) { me.doLoadOnRender(); } else { me.mon(target, 'render', me.doLoadOnRender, me); } } }, doLoadOnRender: function() { var loadOnRender = this.loadOnRender; this.load(Ext.isObject(loadOnRender) ? loadOnRender : null); }, 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.SizeModel', { constructor: function(config) { var me = this, SizeModel = me.self, sizeModelsArray = SizeModel.sizeModelsArray, name; Ext.apply(me, config); me[name = me.name] = true; me.fixed = !(me.auto = me.natural || me.shrinkWrap); sizeModelsArray[me.ordinal = sizeModelsArray.length] = SizeModel[name] = SizeModel.sizeModels[name] = me; }, statics: { sizeModelsArray: [], sizeModels: {} }, calculated: false, configured: false, constrainedMax: false, constrainedMin: false, natural: false, shrinkWrap: false, calculatedFromConfigured: false, calculatedFromNatural: false, calculatedFromShrinkWrap: false, names: null }, function() { var SizeModel = this, sizeModelsArray = SizeModel.sizeModelsArray, i, j, n, pairs, sizeModel; new SizeModel({ name: 'calculated' }); new SizeModel({ name: 'configured', names: { width: 'width', height: 'height' } }); new SizeModel({ name: 'natural' }); new SizeModel({ name: 'shrinkWrap' }); new SizeModel({ name: 'calculatedFromConfigured', configured: true, calculatedFrom: true, names: { width: 'width', height: 'height' } }); new SizeModel({ name: 'calculatedFromNatural', natural: true, calculatedFrom: true }); new SizeModel({ name: 'calculatedFromShrinkWrap', shrinkWrap: true, calculatedFrom: true }); new SizeModel({ name: 'constrainedMax', configured: true, constrained: true, names: { width: 'maxWidth', height: 'maxHeight' } }); new SizeModel({ name: 'constrainedMin', configured: true, constrained: true, names: { width: 'minWidth', height: 'minHeight' } }); new SizeModel({ name: 'constrainedDock', configured: true, constrained: true, constrainedByMin: true, names: { width: 'dockConstrainedWidth', height: 'dockConstrainedHeight' } }); for (i = 0 , n = sizeModelsArray.length; i < n; ++i) { sizeModel = sizeModelsArray[i]; sizeModel.pairsByHeightOrdinal = pairs = []; for (j = 0; j < n; ++j) { pairs.push({ width: sizeModel, height: sizeModelsArray[j] }); } } }); Ext.define('Ext.layout.Layout', { mixins: [ 'Ext.mixin.Factoryable' ], requires: [ 'Ext.XTemplate', 'Ext.layout.SizeModel' ], uses: [ 'Ext.layout.Context' ], factoryConfig: { type: 'layout' }, isLayout: true, initialized: false, running: false, needsItemSize: true, setsItemSize: true, autoSizePolicy: { readsWidth: 1, readsHeight: 1, setsWidth: 0, setsHeight: 0 }, $configPrefixed: false, $configStrict: false, constructor: function(config) { var me = this; me.id = Ext.id(null, me.type + '-'); me.initConfig(config); delete me.type; me.layoutCount = 0; }, beginLayout: Ext.emptyFn, beginLayoutCycle: function(ownerContext) { var me = this, context = me.context, changed; if (me.lastWidthModel !== ownerContext.widthModel) { if (me.lastWidthModel) { changed = true; } me.lastWidthModel = ownerContext.widthModel; } if (me.lastHeightModel !== ownerContext.heightModel) { if (me.lastWidthModel) { changed = true; } me.lastHeightModel = ownerContext.heightModel; } if (changed) { (context = ownerContext.context).clearTriggers(me, false); context.clearTriggers(me, true); me.triggerCount = 0; } }, finishedLayout: function(ownerContext) { this.lastWidthModel = ownerContext.widthModel; this.lastHeightModel = ownerContext.heightModel; this.ownerContext = null; }, redoLayout: Ext.emptyFn, undoLayout: Ext.emptyFn, getAnimatePolicy: function() { return this.animatePolicy; }, getItemSizePolicy: function(item) { return this.autoSizePolicy; }, getScrollerEl: Ext.emptyFn, isItemBoxParent: function(itemContext) { return false; }, isItemLayoutRoot: function(item) { var sizeModel = item.getSizeModel(), width = sizeModel.width, height = sizeModel.height; if (!item.componentLayout.lastComponentSize && (width.calculated || height.calculated)) { return false; } return !width.shrinkWrap && !height.shrinkWrap; }, isItemShrinkWrap: function(item) { return item.shrinkWrap; }, isRunning: function() { return !!this.ownerContext; }, getItemsRenderTree: function(items, renderCfgs) { var length = items.length, i, item, itemConfig, result; if (length) { result = []; for (i = 0; i < length; ++i) { item = items[i]; if (!item.rendered) { if (renderCfgs && (renderCfgs[item.id] !== undefined)) { itemConfig = renderCfgs[item.id]; } else { this.configureItem(item); itemConfig = item.getRenderTree(); if (renderCfgs) { renderCfgs[item.id] = itemConfig; } } if (itemConfig) { result.push(itemConfig); } } } } return result; }, finishRender: Ext.emptyFn, finishRenderItems: function(target, items) { var length = items.length, i, item; for (i = 0; i < length; i++) { item = items[i]; if (item.rendering) { item.finishRender(i); } } }, renderChildren: function() { var me = this, items = me.getLayoutItems(), target = me.getRenderTarget(); me.renderItems(items, target); }, renderItems: function(items, target) { var me = this, ln = items.length, i = 0, item; if (ln) { Ext.suspendLayouts(); for (; i < ln; i++) { item = items[i]; if (item && !item.rendered) { me.renderItem(item, target, i); } else if (!me.isValidParent(item, target, i)) { me.moveItem(item, target, i); } else { me.configureItem(item); } } Ext.resumeLayouts(true); } }, isValidParent: function(item, target, position) { var targetDom = (target && target.dom) || target, itemDom = this.getItemLayoutEl(item); if (itemDom && targetDom) { if (typeof position === 'number') { position = this.getPositionOffset(position); return itemDom === targetDom.childNodes[position]; } return itemDom.parentNode === targetDom; } return false; }, getItemLayoutEl: function(item) { var dom = item.el ? item.el.dom : Ext.getDom(item), parentNode = dom.parentNode, className; if (parentNode) { className = parentNode.className; if (className && className.indexOf(Ext.baseCSSPrefix + 'resizable-wrap') !== -1) { dom = dom.parentNode; } } return dom; }, getPositionOffset: function(position) { return position; }, configureItem: function(item) { item.ownerLayout = this; }, renderItem: function(item, target, position) { var me = this; if (!item.rendered) { me.configureItem(item); item.render(target, position); } }, moveItem: function(item, target, position) { target = target.dom || target; if (typeof position === 'number') { position = target.childNodes[position]; } target.insertBefore(item.el.dom, position || null); item.container = Ext.get(target); this.configureItem(item); }, onContentChange: function() { this.owner.updateLayout(); return true; }, initLayout: function() { this.initialized = true; }, setOwner: function(owner) { this.owner = owner; }, getLayoutItems: function() { return []; }, onAdd: function(item) { item.ownerLayout = this; }, onRemove: Ext.emptyFn, onDestroy: Ext.emptyFn, afterRemove: function(item) { var me = this, el = item.el, owner = me.owner, removeClasses; if (item.rendered) { removeClasses = [].concat(me.itemCls || []); if (owner.itemCls) { removeClasses = Ext.Array.push(removeClasses, owner.itemCls); } if (removeClasses.length) { el.removeCls(removeClasses); } } delete item.ownerLayout; }, afterCollapse: function(owner, animated) { if (animated) { this.onContentChange(owner); } }, afterExpand: function(owner, animated) { if (animated) { this.onContentChange(owner); } }, destroy: function() { var me = this, target; if (me.targetCls) { target = me.getTarget(); if (target) { target.removeCls(me.targetCls); } } me.onDestroy(); }, sortWeightedItems: function(items, reverseProp) { for (var i = 0, length = items.length; i < length; ++i) { items[i].$i = i; } Ext.Array.sort(items, function(item1, item2) { var ret = item2.weight - item1.weight; if (!ret) { ret = item1.$i - item2.$i; if (item1[reverseProp]) { ret = -ret; } } return ret; }); for (i = 0; i < length; ++i) { delete items[i].$i; } } }, function() { var Layout = this; Layout.prototype.sizeModels = Layout.sizeModels = Ext.layout.SizeModel.sizeModels; }); Ext.define('Ext.layout.container.Container', { extend: 'Ext.layout.Layout', alias: 'layout.container', alternateClassName: 'Ext.layout.ContainerLayout', mixins: [ 'Ext.util.ElementContainer' ], requires: [ 'Ext.XTemplate' ], type: 'container', beginCollapse: Ext.emptyFn, beginExpand: Ext.emptyFn, animatePolicy: null, activeItemCount: 0, renderTpl: [ '{%this.renderBody(out,values)%}' ], usesContainerHeight: true, usesContainerWidth: true, usesHeight: true, usesWidth: true, constructor: function() { this.callParent(arguments); this.mixins.elementCt.constructor.call(this); }, destroy: function() { this.callParent(); this.mixins.elementCt.destroy.call(this); }, beginLayout: function(ownerContext) { this.callParent(arguments); ownerContext.targetContext = ownerContext.paddingContext = ownerContext.getEl('getTarget', this); this.cacheChildItems(ownerContext); }, beginLayoutCycle: function(ownerContext, firstCycle) { var me = this; me.callParent(arguments); if (firstCycle) { if (me.usesContainerHeight) { ++ownerContext.consumersContainerHeight; } if (me.usesContainerWidth) { ++ownerContext.consumersContainerWidth; } } }, cacheChildItems: function(ownerContext) { var me = this, context, childItems, items, length, i; if (me.needsItemSize || me.setsItemSize) { context = ownerContext.context; childItems = ownerContext.childItems = []; items = ownerContext.visibleItems = me.getVisibleItems(); length = items.length; for (i = 0; i < length; ++i) { childItems.push(context.getCmp(items[i])); } } }, cacheElements: function() { var owner = this.owner; this.attachChildEls(owner.el, owner); }, calculate: function(ownerContext) { var props = ownerContext.props, el = ownerContext.el; if (ownerContext.widthModel.shrinkWrap && isNaN(props.width)) { ownerContext.setContentWidth(el.getWidth()); } if (ownerContext.heightModel.shrinkWrap && isNaN(props.height)) { ownerContext.setContentHeight(el.getHeight()); } }, configureItem: function(item) { var me = this, itemCls = me.itemCls, ownerItemCls = me.owner.itemCls, needsCopy, addClasses; item.ownerLayout = me; if (itemCls) { if (typeof itemCls === 'string') { addClasses = [ itemCls ]; } else { addClasses = itemCls; needsCopy = !!addClasses; } } if (ownerItemCls) { if (needsCopy) { addClasses = Ext.Array.clone(addClasses); } addClasses = Ext.Array.push(addClasses || [], ownerItemCls); } if (addClasses) { item.addCls(addClasses); } }, doRenderBody: function(out, renderData) { this.renderItems(out, renderData); this.renderContent(out, renderData); }, doRenderContainer: function(out, renderData) { var me = renderData.$comp.layout, tpl = me.getRenderTpl(), data = me.getRenderData(); tpl.applyOut(data, out); }, doRenderItems: function(out, renderData) { var me = renderData.$layout, tree = me.getRenderTree(); if (tree) { Ext.DomHelper.generateMarkup(tree, out); } }, finishRender: function() { var me = this, target, items; me.callParent(); me.cacheElements(); target = me.getRenderTarget(); items = me.getLayoutItems(); me.finishRenderItems(target, items); }, notifyOwner: function() { if (!this._hasTargetWarning && this.targetCls && !this.getTarget().hasCls(this.targetCls)) { this._hasTargetWarning = true; Ext.log.warn('targetCls is missing. This may mean that getTargetEl() is being overridden but not applyTargetCls(). ' + this.owner.id); } this.owner.afterLayout(this); }, getContainerSize: function(ownerContext, inDom) { var targetContext = ownerContext.targetContext, frameInfo = targetContext.getFrameInfo(), padding = ownerContext.paddingContext.getPaddingInfo(), got = 0, needed = 0, gotWidth, gotHeight, width, height; if (!ownerContext.widthModel.shrinkWrap) { ++needed; width = inDom ? targetContext.getDomProp('width') : targetContext.getProp('width'); gotWidth = (typeof width === 'number'); if (gotWidth) { ++got; width -= frameInfo.width + padding.width; if (width < 0) { width = 0; } } } if (!ownerContext.heightModel.shrinkWrap) { ++needed; height = inDom ? targetContext.getDomProp('height') : targetContext.getProp('height'); gotHeight = (typeof height === 'number'); if (gotHeight) { ++got; height -= frameInfo.height + padding.height; if (height < 0) { height = 0; } } } return { width: width, height: height, needed: needed, got: got, gotAll: got === needed, gotWidth: gotWidth, gotHeight: gotHeight }; }, getPositionOffset: function(position) { if (!this.createsInnerCt) { var offset = this.owner.itemNodeOffset; if (offset) { position += offset; } } return position; }, getLayoutItems: function() { var owner = this.owner, items = owner && owner.items; return (items && items.items) || []; }, getRenderData: function() { var comp = this.owner; return { $comp: comp, $layout: this, ownerId: comp.id }; }, getRenderedItems: function() { var me = this, target = me.getRenderTarget(), 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; }, getRenderTarget: function() { return this.owner.getTargetEl(); }, getElementTarget: function() { return this.getRenderTarget(); }, getRenderTpl: function() { var me = this, renderTpl = Ext.XTemplate.getTpl(this, 'renderTpl'); if (!renderTpl.renderContent) { me.owner.setupRenderTpl(renderTpl); } return renderTpl; }, getRenderTree: function() { var result, items = this.owner.items, itemsGen, renderCfgs = {}; do { itemsGen = items.generation; result = this.getItemsRenderTree(this.getLayoutItems(), renderCfgs); } while (items.generation !== itemsGen); return result; }, renderChildren: function() { var me = this, ownerItems = me.owner.items, target = me.getRenderTarget(), itemsGen, items; do { itemsGen = ownerItems.generation; items = me.getLayoutItems(); me.renderItems(items, target); } while (ownerItems.generation !== itemsGen); }, getScrollbarsNeeded: function(width, height, contentWidth, contentHeight) { var scrollbarSize = Ext.getScrollbarSize(), hasWidth = typeof width === 'number', hasHeight = typeof height === 'number', needHorz = 0, needVert = 0; if (!scrollbarSize.width) { return 0; } if (hasHeight && height < contentHeight) { needVert = 2; width -= scrollbarSize.width; } if (hasWidth && width < contentWidth) { needHorz = 1; if (!needVert && hasHeight) { height -= scrollbarSize.height; if (height < contentHeight) { needVert = 2; } } } return needVert + needHorz; }, getTarget: function() { return this.owner.getTargetEl(); }, getVisibleItems: function() { var target = this.getRenderTarget(), 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 && !item.floated) { visibleItems.push(item); } } return visibleItems; }, getMoveAfterIndex: function(after) { return this.owner.items.indexOf(after) + 1; }, moveItemBefore: function(item, before) { var owner = this.owner, items = owner.items, index = items.indexOf(item), toIndex; if (item === before) { return item; } if (before) { toIndex = items.indexOf(before); if (index > -1 && index < toIndex) { --toIndex; } } else { toIndex = items.length; } return owner.insert(toIndex, item); }, setupRenderTpl: function(renderTpl) { renderTpl.renderBody = this.doRenderBody; renderTpl.renderContainer = this.doRenderContainer; renderTpl.renderItems = this.doRenderItems; }, getContentTarget: function() { return this.owner.getDefaultContentTarget(); }, onAdd: function(item) { if (!item.liquidLayout) { ++this.activeItemCount; } this.callParent([ item ]); }, onRemove: function(item) { if (!item.liquidLayout) { --this.activeItemCount; } this.callParent([ item ]); } }); Ext.define('Ext.layout.container.Auto', { alias: [ 'layout.auto', 'layout.autocontainer' ], extend: 'Ext.layout.container.Container', type: 'autocontainer', childEls: [ 'outerCt', 'innerCt' ], reserveScrollbar: false, managePadding: true, manageOverflow: false, needsItemSize: false, setsItemSize: false, lastOverflowAdjust: { width: 0, height: 0 }, outerCtCls: Ext.baseCSSPrefix + 'autocontainer-outerCt', innerCtCls: Ext.baseCSSPrefix + 'autocontainer-innerCt', renderTpl: [ '' ], beginLayout: function(ownerContext) { this.callParent(arguments); this.initContextItems(ownerContext); }, beforeLayoutCycle: function(ownerContext) { var comp = this.owner, inheritedState = comp.inheritedState, inheritedStateInner = comp.inheritedStateInner; if (!inheritedState || inheritedState.invalid) { inheritedState = comp.getInherited(); inheritedStateInner = comp.inheritedStateInner; } if (ownerContext.widthModel.shrinkWrap) { inheritedStateInner.inShrinkWrapTable = true; } else { delete inheritedStateInner.inShrinkWrapTable; } }, beginLayoutCycle: function(ownerContext) { var me = this, outerCt = me.outerCt, lastOuterCtWidth = me.lastOuterCtWidth || '', lastOuterCtHeight = me.lastOuterCtHeight || '', lastOuterCtTableLayout = me.lastOuterCtTableLayout || '', state = ownerContext.state, overflowXStyle, outerCtWidth, outerCtHeight, outerCtTableLayout, inheritedStateInner; me.callParent(arguments); outerCtWidth = outerCtHeight = outerCtTableLayout = ''; if (!ownerContext.widthModel.shrinkWrap) { outerCtWidth = '100%'; inheritedStateInner = me.owner.inheritedStateInner; overflowXStyle = me.getOverflowXStyle(ownerContext); outerCtTableLayout = (inheritedStateInner.inShrinkWrapTable || overflowXStyle === 'auto' || overflowXStyle === 'scroll') ? '' : 'fixed'; } if (!ownerContext.heightModel.shrinkWrap && !Ext.supports.PercentageHeightOverflowBug) { outerCtHeight = '100%'; } if ((outerCtWidth !== lastOuterCtWidth) || me.hasOuterCtPxWidth) { outerCt.setStyle('width', outerCtWidth); me.lastOuterCtWidth = outerCtWidth; me.hasOuterCtPxWidth = false; } if (outerCtTableLayout !== lastOuterCtTableLayout) { outerCt.setStyle('table-layout', outerCtTableLayout); me.lastOuterCtTableLayout = outerCtTableLayout; } if ((outerCtHeight !== lastOuterCtHeight) || me.hasOuterCtPxHeight) { outerCt.setStyle('height', outerCtHeight); me.lastOuterCtHeight = outerCtHeight; me.hasOuterCtPxHeight = false; } if (me.hasInnerCtPxHeight) { me.innerCt.setStyle('height', ''); me.hasInnerCtPxHeight = false; } state.overflowAdjust = state.overflowAdjust || me.lastOverflowAdjust; }, calculate: function(ownerContext) { var me = this, state = ownerContext.state, containerSize = me.getContainerSize(ownerContext, true), calculatedItems = state.calculatedItems || (state.calculatedItems = me.calculateItems ? me.calculateItems(ownerContext, containerSize) : true); me.setCtSizeIfNeeded(ownerContext, containerSize); if (calculatedItems && ownerContext.hasDomProp('containerChildrenSizeDone')) { me.calculateContentSize(ownerContext); if (containerSize.gotAll) { if (me.manageOverflow && !ownerContext.state.secondPass && !me.reserveScrollbar) { me.calculateOverflow(ownerContext, containerSize); } return; } } me.done = false; }, calculateContentSize: function(ownerContext) { var me = this, containerDimensions = ((ownerContext.widthModel.shrinkWrap ? 1 : 0) | (ownerContext.heightModel.shrinkWrap ? 2 : 0)), calcWidth = (containerDimensions & 1) || undefined, calcHeight = (containerDimensions & 2) || undefined, needed = 0, props = ownerContext.props; if (calcWidth) { if (isNaN(props.contentWidth)) { ++needed; } else { calcWidth = undefined; } } if (calcHeight) { if (isNaN(props.contentHeight)) { ++needed; } else { calcHeight = undefined; } } if (needed) { if (calcWidth && !ownerContext.setContentWidth(me.measureContentWidth(ownerContext))) { me.done = false; } if (calcHeight && !ownerContext.setContentHeight(me.measureContentHeight(ownerContext))) { me.done = false; } } }, calculateOverflow: function(ownerContext) { var me = this, width, height, scrollbarSize, scrollbars, xauto, yauto, targetEl; xauto = (me.getOverflowXStyle(ownerContext) === 'auto'); yauto = (me.getOverflowYStyle(ownerContext) === 'auto'); if (xauto || yauto) { scrollbarSize = Ext.getScrollbarSize(); targetEl = ownerContext.overflowContext.el.dom; scrollbars = 0; if (targetEl.scrollWidth > targetEl.clientWidth) { scrollbars |= 1; } if (targetEl.scrollHeight > targetEl.clientHeight) { scrollbars |= 2; } width = (yauto && (scrollbars & 2)) ? scrollbarSize.width : 0; height = (xauto && (scrollbars & 1)) ? scrollbarSize.height : 0; if (width !== me.lastOverflowAdjust.width || height !== me.lastOverflowAdjust.height) { me.done = false; ownerContext.invalidate({ state: { overflowAdjust: { width: width, height: height }, overflowState: scrollbars, secondPass: true } }); } } }, completeLayout: function(ownerContext) { this.lastOverflowAdjust = ownerContext.state.overflowAdjust; }, doRenderBody: function(out, renderData) { var me = renderData.$layout, XTemplate = Ext.XTemplate, beforeBodyTpl = me.beforeBodyTpl, afterBodyTpl = me.afterBodyTpl; if (beforeBodyTpl) { XTemplate.getTpl(me, 'beforeBodyTpl').applyOut(renderData, out); } this.renderItems(out, renderData); this.renderContent(out, renderData); if (afterBodyTpl) { XTemplate.getTpl(me, 'afterBodyTpl').applyOut(renderData, out); } }, doRenderPadding: function(out, renderData) { var me = renderData.$layout, owner = renderData.$layout.owner, padding = owner[owner.contentPaddingProperty]; if (me.managePadding && padding) { out.push('padding:', owner.unitizeBox(padding)); } }, finishedLayout: function(ownerContext) { var innerCt = this.innerCt; this.callParent(arguments); if (Ext.isIE8) { innerCt.repaint(); } if (Ext.isOpera) { innerCt.setStyle('position', 'relative'); innerCt.dom.scrollWidth; innerCt.setStyle('position', ''); } }, getContainerSize: function(ownerContext, inDom) { var size = this.callParent(arguments), overflowAdjust = ownerContext.state.overflowAdjust; if (overflowAdjust) { size.width -= overflowAdjust.width; size.height -= overflowAdjust.height; } return size; }, getRenderData: function() { var me = this, data = me.callParent(); data.innerCtCls = me.innerCtCls; data.outerCtCls = me.outerCtCls; return data; }, getRenderTarget: function() { return this.innerCt; }, getElementTarget: function() { return this.innerCt; }, getOverflowXStyle: function(ownerContext) { return ownerContext.overflowXStyle || (ownerContext.overflowXStyle = this.owner.scrollFlags.overflowX || ownerContext.overflowContext.getStyle('overflow-x')); }, getOverflowYStyle: function(ownerContext) { return ownerContext.overflowYStyle || (ownerContext.overflowYStyle = this.owner.scrollFlags.overflowY || ownerContext.overflowContext.getStyle('overflow-y')); }, initContextItems: function(ownerContext) { var me = this, target = ownerContext.target, overflowEl = me.owner.getOverflowEl(); ownerContext.outerCtContext = ownerContext.getEl('outerCt', me); ownerContext.innerCtContext = ownerContext.getEl('innerCt', me); ownerContext.overflowContext = (overflowEl === ownerContext.el) ? ownerContext : ownerContext.getEl(overflowEl); if (target[target.contentPaddingProperty] !== undefined) { ownerContext.paddingContext = ownerContext.innerCtContext; } }, initLayout: function() { var me = this, scrollbarWidth = Ext.getScrollbarSize().width, owner = me.owner; me.callParent(); if (scrollbarWidth && me.manageOverflow && !me.hasOwnProperty('lastOverflowAdjust')) { if (owner.scrollable || me.reserveScrollbar) { me.lastOverflowAdjust = { width: scrollbarWidth, height: 0 }; } } }, measureContentHeight: function(ownerContext) { var contentHeight = this.outerCt.getHeight(), target = ownerContext.target; if (this.managePadding && (target[target.contentPaddingProperty] === undefined)) { contentHeight += ownerContext.targetContext.getPaddingInfo().height; } return contentHeight; }, measureContentWidth: function(ownerContext) { var dom, style, old, contentWidth, target; if (this.chromeCellMeasureBug) { dom = this.innerCt.dom; style = dom.style; old = style.display; if (old === 'table-cell') { style.display = ''; dom.offsetWidth; style.display = old; } } if (Ext.isSafari) { dom = this.outerCt.dom; style = dom.style; style.display = 'table-cell'; dom.offsetWidth; dom.style.display = ''; } contentWidth = this.outerCt.getWidth(); target = ownerContext.target; if (this.managePadding && (target[target.contentPaddingProperty] === undefined)) { contentWidth += ownerContext.targetContext.getPaddingInfo().width; } return contentWidth; }, setCtSizeIfNeeded: function(ownerContext, containerSize) { var me = this, height = containerSize.height, padding = ownerContext.paddingContext.getPaddingInfo(), targetEl = me.getTarget(), overflowXStyle = me.getOverflowXStyle(ownerContext), canOverflowX = (overflowXStyle === 'auto' || overflowXStyle === 'scroll'), scrollbarSize = Ext.getScrollbarSize(), needsOuterHeight, needsInnerHeight; if (height && !ownerContext.heightModel.shrinkWrap) { if (Ext.supports.PercentageHeightOverflowBug) { needsOuterHeight = true; } if (Ext.isIE8) { needsInnerHeight = true; } if ((needsOuterHeight || needsInnerHeight) && canOverflowX && (targetEl.dom.scrollWidth > targetEl.dom.clientWidth)) { height = Math.max(height - scrollbarSize.height, 0); } if (needsOuterHeight) { ownerContext.outerCtContext.setProp('height', height + padding.height); me.hasOuterCtPxHeight = true; } if (needsInnerHeight) { ownerContext.innerCtContext.setProp('height', height); me.hasInnerCtPxHeight = true; } } }, setupRenderTpl: function(renderTpl) { this.callParent(arguments); renderTpl.renderPadding = this.doRenderPadding; }, getContentTarget: function() { return this.innerCt; }, getScrollerEl: function() { return this.outerCt; } }, function() { this.prototype.chromeCellMeasureBug = Ext.isChrome && Ext.chromeVersion >= 26; }); Ext.define('Ext.ZIndexManager', { alternateClassName: 'Ext.WindowGroup', requires: [ 'Ext.util.SorterCollection', 'Ext.util.FilterCollection', 'Ext.GlobalEvents' ], statics: { zBase: 9000, activeCounter: 0 }, constructor: function(container) { var me = this; me.id = Ext.id(null, 'zindex-mgr-'); me.zIndexStack = new Ext.util.Collection({ sorters: { sorterFn: function(comp1, comp2) { var ret = (comp1.alwaysOnTop || 0) - (comp2.alwaysOnTop || 0); if (!ret) { ret = comp1.getActiveCounter() - comp2.getActiveCounter(); } return ret; } }, filters: { filterFn: function(comp) { return comp.isVisible(); } } }); me.zIndexStack.addObserver(me); me.front = null; me.globalListeners = Ext.GlobalEvents.on({ hide: me.onComponentShowHide, show: me.onComponentShowHide, scope: me, destroyable: true }); if (container) { if (container.isContainer) { container.on('resize', me.onContainerResize, me); me.zseed = Ext.Number.from(me.rendered ? container.getEl().getStyle('zIndex') : undefined, me.getNextZSeed()); me.targetEl = container.getTargetEl(); me.container = container; } else { Ext.on('resize', me.onContainerResize, me); me.zseed = me.getNextZSeed(); me.targetEl = Ext.get(container); } } else { me.zseed = me.getNextZSeed(); Ext.onInternalReady(function() { Ext.on('resize', me.onContainerResize, me); me.targetEl = Ext.getBody(); }); } }, getId: function() { return this.id; }, getNextZSeed: function() { return (Ext.ZIndexManager.zBase += 10000); }, setBase: function(baseZIndex) { this.zseed = baseZIndex; return this.onCollectionSort(); }, onCollectionSort: function() { var me = this, oldFront = me.front, zIndex = me.zseed, a = me.zIndexStack.getRange(), len = a.length, i, comp, topModal, topVisible, doFocus = false; for (i = 0; i < len; i++) { comp = a[i]; zIndex = comp.setZIndex(zIndex); if (!comp.hidden) { topVisible = comp; if (comp.modal) { topModal = comp; } } } if (topVisible !== oldFront) { if (oldFront && !oldFront.destroying) { oldFront.setActive(false); } if (topVisible) { doFocus = topVisible.modal || ((!oldFront || oldFront.isVisible()) && ((topVisible.focusOnToFront && !topVisible.preventFocusOnActivate))) && topVisible.isFocusable(true); topVisible.setActive(true, doFocus); } } me.front = topVisible; if (topModal) { me.showModalMask(topModal); } else { me.hideModalMask(); } return zIndex; }, onComponentUpdate: function(comp) { if (this.zIndexStack.contains(comp)) { this.zIndexStack.sort(); } }, onComponentRender: function(comp) { this.zIndexStack.itemChanged(comp, 'hidden'); }, onComponentShowHide: function(comp) { var zIndexStack = this.zIndexStack; if (comp.isFloating() && !this.hidingAll && (zIndexStack.getSource() || zIndexStack).contains(comp)) { zIndexStack.itemChanged(comp, 'hidden'); zIndexStack.sort(); } }, register: function(comp) { var me = this; if (comp.zIndexManager) { comp.zIndexManager.unregister(comp); } comp.zIndexManager = me; if (!comp.rendered) { comp.on('render', me.onComponentRender, me, { single: true }); } me.zIndexStack.add(comp); }, unregister: function(comp) { var me = this; delete comp.zIndexManager; comp.un('render', me.onComponentRender, me); me.zIndexStack.remove(comp); me.onCollectionSort(); }, get: function(id) { return id.isComponent ? id : this.zIndexStack.get(id); }, bringToFront: function(comp, preventFocus) { var me = this, zIndexStack = me.zIndexStack, oldFront = zIndexStack.last(), newFront, preventFocusSetting; comp = me.get(comp); if (!comp || zIndexStack.find('alwaysOnTop', true)) { return false; } preventFocusSetting = comp.preventFocusOnActivate; comp.preventFocusOnActivate = preventFocus; comp.setActiveCounter(++Ext.ZIndexManager.activeCounter); comp.preventFocusOnActivate = preventFocusSetting; newFront = zIndexStack.last(); return (newFront === comp && newFront !== oldFront); }, sendToBack: function(comp) { comp = this.get(comp); if (comp) { comp.setActiveCounter(0); } return comp || null; }, hideAll: function() { var all = this.zIndexStack.getRange(), len = all.length, i; this.hidingAll = true; for (i = 0; i < len; i++) { all[i].hide(); } this.hidingAll = false; }, hide: function() { var me = this, activeElement = Ext.Element.getActiveElement(), all = me.tempHidden = me.zIndexStack.getRange(), len = all.length, i, comp; me.focusRestoreElement = null; for (i = 0; i < len; i++) { comp = all[i]; if (comp.el.contains(activeElement)) { me.focusRestoreElement = activeElement; } comp.el.hide(); comp.hidden = true; } }, show: function() { var me = this, i, tempHidden = me.tempHidden, len = tempHidden ? tempHidden.length : 0, comp; for (i = 0; i < len; i++) { comp = tempHidden[i]; comp.el.show(); comp.hidden = false; comp.setPosition(comp.x, comp.y); } me.tempHidden = null; if (me.focusRestoreElement) { me.focusRestoreElement.focus(); } }, getActive: function() { return this.zIndexStack.last(); }, getBy: function(fn, scope) { return this.zIndexStack.filterBy(fn, scope).getRange(); }, each: function(fn, scope) { this.zIndexStack.each(fn, scope); }, eachBottomUp: function(fn, scope) { var stack = this.zIndexStack.getRange(), i, len = stack.length, comp; for (i = 0; i < len; i++) { comp = stack[i]; if (comp.isComponent && fn.call(scope || comp, comp) === false) { return; } } }, eachTopDown: function(fn, scope) { var stack = this.zIndexStack.getRange(), i, comp; for (i = stack.length; i-- > 0; ) { comp = stack[i]; if (comp.isComponent && fn.call(scope || comp, comp) === false) { return; } } }, destroy: function() { var me = this, stack = me.zIndexStack.getRange(), len = stack.length, i; for (i = 0; i < len; i++) { Ext.destroy(stack[i]); } Ext.destroy(me.mask, me.maskShim, me.zIndexStack, me.globalListeners); me.zIndexStack = me.container = me.targetEl = me.globalListeners = null; }, privates: { getMaskBox: function() { var maskTarget = this.mask.maskTarget; if (maskTarget.dom === document.body) { return { height: Math.max(document.body.scrollHeight, Ext.dom.Element.getDocumentHeight()), width: Math.max(document.body.scrollWidth, document.documentElement.clientWidth), x: 0, y: 0 }; } else { return maskTarget.getBox(); } }, hideModalMask: function() { var mask = this.mask, maskShim = this.maskShim, maskTarget, tabbableAttr; if (mask && mask.isVisible()) { maskTarget = mask.maskTarget; tabbableAttr = 'data-savedtabindex-' + maskTarget.getId(); maskTarget.restoreChildrenTabbableState(tabbableAttr); maskTarget.restoreTabbableState(tabbableAttr); mask.maskTarget = undefined; mask.hide(); if (maskShim) { maskShim.hide(); } } }, onContainerResize: function() { var me = this, mask = me.mask, maskShim = me.maskShim, viewSize; if (mask && mask.isVisible()) { mask.hide(); if (maskShim) { maskShim.hide(); } viewSize = me.getMaskBox(); if (maskShim) { maskShim.setSize(viewSize); maskShim.show(); } mask.setSize(viewSize); mask.show(); } }, onMaskClick: function() { if (this.front) { this.front.focus(); } }, showModalMask: function(comp) { var me = this, compEl = comp.el, zIndex = compEl.getStyle('zIndex') - 4, maskTarget = comp.floatParent ? comp.floatParent.getTargetEl() : comp.container, mask = me.mask, shim = me.maskShim, viewSize, tabbableAttr, tempTabbableAttr, tabbables; if (!mask) { me.mask = mask = Ext.getBody().createChild({ 'data-sticky': true, role: 'presentation', cls: Ext.baseCSSPrefix + 'mask ' + Ext.baseCSSPrefix + 'border-box', style: 'height:0;width:0' }); mask.setVisibilityMode(Ext.Element.DISPLAY); mask.on('click', me.onMaskClick, me); } else { me.hideModalMask(); } mask.maskTarget = maskTarget; viewSize = me.getMaskBox(); if (shim) { shim.setStyle('zIndex', zIndex); shim.show(); shim.setBox(viewSize); } mask.setStyle('zIndex', zIndex); tabbableAttr = 'data-savedtabindex-' + maskTarget.getId(); tempTabbableAttr = tabbableAttr + '-temp'; tabbables = compEl.findTabbableElements(); if (tabbables.length) { compEl.saveTabbableState(tempTabbableAttr); compEl.saveChildrenTabbableState(tempTabbableAttr); } maskTarget.saveTabbableState(tabbableAttr); maskTarget.saveChildrenTabbableState(tabbableAttr); if (tabbables.length) { compEl.restoreChildrenTabbableState(tempTabbableAttr); compEl.restoreTabbableState(tempTabbableAttr); } mask.show(); mask.setBox(viewSize); } } }, function() { Ext.WindowManager = Ext.WindowMgr = new this(); }); Ext.define('Ext.container.Container', { extend: 'Ext.Component', xtype: 'container', alternateClassName: [ 'Ext.Container', 'Ext.AbstractContainer' ], requires: [ 'Ext.util.MixedCollection', 'Ext.layout.container.Auto', 'Ext.ZIndexManager' ], mixins: [ 'Ext.mixin.Queryable' ], renderTpl: '{%this.renderContainer(out,values)%}', isContainer: true, autoDestroy: true, defaultType: 'panel', detachOnRemove: true, items: undefined, layout: 'auto', suspendLayout: false, _applyDefaultsOptions: { defaults: true, strict: false }, ariaRole: 'presentation', baseCls: Ext.baseCSSPrefix + 'container', layoutCounter: 0, add: function() { var me = this, args = Ext.Array.slice(arguments), index = (typeof args[0] === 'number') ? args.shift() : -1, layout = me.getLayout(), needsLayout = false, addingArray, items, i, length, item, pos, ret, instanced; if (args.length === 1 && Ext.isArray(args[0])) { items = args[0]; addingArray = true; } else { items = args; } if (me.rendered) { Ext.suspendLayouts(); } ret = items = me.prepareItems(items, true); length = items.length; if (!addingArray && length === 1) { ret = items[0]; } for (i = 0; i < length; i++) { item = items[i]; if (!item) { Ext.Error.raise("Cannot add null item to Container with itemId/id: " + me.getItemId()); } if (item.isDestroyed) { Ext.Error.raise("Cannot add destroyed item '" + item.getId() + "' to Container '" + me.getId() + "'"); } pos = (index < 0) ? me.items.length : (index + i); instanced = !!item.instancedCmp; delete item.instancedCmp; if (item.floating) { me.floatingItems.add(item); item.onAdded(me, pos, instanced); delete item.initOwnerCt; if (me.hasListeners.add) { me.fireEvent('add', me, item, pos); } } else if ((!me.hasListeners.beforeadd || me.fireEvent('beforeadd', me, item, pos) !== false) && me.onBeforeAdd(item) !== false) { me.items.insert(pos, item); item.onAdded(me, pos, instanced); delete item.initOwnerCt; me.onAdd(item, pos); layout.onAdd(item, pos); needsLayout = true; if (me.hasListeners.add) { me.fireEvent('add', me, item, pos); } } } if (needsLayout) { me.updateLayout(); } if (me.rendered) { Ext.resumeLayouts(true); } return ret; }, onAdded: function(container, pos, instanced) { this.callParent(arguments); if (instanced) { Ext.ComponentManager.markReferencesDirty(); } }, onRemoved: function(destroying) { var refHolder; if (!destroying) { refHolder = this.lookupReferenceHolder(); if (refHolder) { Ext.ComponentManager.markReferencesDirty(); refHolder.clearReferences(); } } this.callParent(arguments); }, afterComponentLayout: function() { var floaters = this.floatingItems.items, floaterCount = floaters.length, i, floater; this.callParent(arguments); for (i = 0; i < floaterCount; i++) { floater = floaters[i]; if (!floater.rendered && floater.autoShow) { floater.show(); } } }, afterLayout: function(layout) { var me = this, scroller = me.getScrollable(); ++me.layoutCounter; if (scroller && me.layoutCounter > 1) { scroller.refresh(); } if (me.hasListeners.afterlayout) { me.fireEvent('afterlayout', me, layout); } }, onDestroy: function() { this.callParent(); this.refs = null; }, beforeDestroy: function() { var me = this, items = me.items, floatingItems = me.floatingItems, c; if (items) { while ((c = items.first())) { me.doRemove(c, true); } } if (floatingItems) { while ((c = floatingItems.first())) { me.doRemove(c, true); } } Ext.destroy(me.layout); me.callParent(); }, beforeRender: function() { var me = this, layout = me.getLayout(), targetCls; me.preventChildDisable = true; me.callParent(); me.preventChildDisable = false; if (!layout.initialized) { layout.initLayout(); } targetCls = layout.targetCls; if (targetCls) { me.applyTargetCls(targetCls); } }, 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 || c, args); } } } return this; }, contains: function(comp, deep) { var result = false; if (deep) { this.cascade(function(c) { if (c.contains && c.contains(comp)) { result = true; return false; } }); return result; } else { return this.items.contains(comp) || this.floatingItems.contains(comp); } }, disable: function(silent, fromParent) { var me = this, wasDisabled = me.disabled, itemsToDisable, len, i; me.callParent([ silent, fromParent ]); if (!fromParent && !me.preventChildDisable && !wasDisabled) { itemsToDisable = me.getChildItemsToDisable(); len = itemsToDisable.length; for (i = 0; i < len; i++) { itemsToDisable[i].disable(silent, true); } } return me; }, doLayout: function() { this.updateLayout(); return this; }, enable: function(silent, fromParent) { var me = this, wasDisabled = me.disabled, itemsToDisable, len, i; me.callParent([ silent, fromParent ]); if (wasDisabled) { itemsToDisable = me.getChildItemsToDisable(); len = itemsToDisable.length; for (i = 0; i < len; i++) { itemsToDisable[i].enable(silent, true); } } return me; }, getChildByElement: function(el, deep) { var item, itemEl, i = 0, it = this.getRefItems(), ln = it.length; el = Ext.getDom(el); for (; i < ln; i++) { item = it[i]; itemEl = item.getEl(); if (itemEl && ((itemEl.dom === el) || itemEl.contains(el))) { return (deep && item.getChildByElement) ? item.getChildByElement(el, deep) : item; } } return null; }, getComponent: function(comp) { if (Ext.isObject(comp)) { comp = comp.getItemId(); } var c = this.items.get(comp); if (!c && typeof comp !== 'number') { c = this.floatingItems.get(comp); } return c; }, getFocusEl: function() { var delegate = this.getDefaultFocus(); if (delegate) { return delegate; } else if (this.focusable) { return this.getTargetEl(); } return undefined; }, getLayout: function() { var me = this, layout = me.layout; if (!layout || !layout.isLayout) { me.setLayout(layout); } return me.layout; }, getRefItems: function(deep) { var me = this, items = me.items.items, len = items.length, i = 0, item, result = []; for (; i < len; i++) { item = items[i]; result[result.length] = item; if (deep && item.getRefItems) { result.push.apply(result, item.getRefItems(true)); } } items = me.floatingItems.items; len = items.length; for (i = 0; i < len; i++) { item = items[i]; result[result.length] = item; if (deep && item.getRefItems) { result.push.apply(result, item.getRefItems(true)); } } return result; }, getDefaultFocus: function() { var defaultFocus = this.defaultFocus, result; if (defaultFocus) { result = this.down(defaultFocus); } return result; }, initComponent: function() { var me = this; me.callParent(); me.getLayout(); me.constructing = true; me.initItems(); if (me.disabled) { me.disabled = false; me.disable(true); } delete me.constructing; }, getReferences: function() { var ComponentManager = Ext.ComponentManager; if (ComponentManager.referencesDirty) { ComponentManager.fixReferences(); } return this.refs || null; }, lookupReference: function(key) { var refs = this.getReferences(); return (refs && refs[key]) || null; }, initItems: function() { var me = this, items = me.items; if (!items || !items.isMixedCollection) { me.items = new Ext.util.AbstractMixedCollection(false, me.getComponentId); me.floatingItems = new Ext.util.MixedCollection(false, me.getComponentId); if (items) { if (!Ext.isArray(items)) { items = [ items ]; } me.add(items); } } }, initInheritedState: function(inheritedState, inheritedStateInner) { var me = this, controller = me.controller, layout = me.layout, session = me.session, viewModel = me.viewModel, reference = me.reference, referenceHolder = me.referenceHolder; me.callParent([ inheritedState, inheritedStateInner ]); if (me.collapsed) { inheritedState.collapsed = true; } if (controller) { inheritedState.referenceHolder = controller; referenceHolder = true; } else if (referenceHolder) { inheritedState.referenceHolder = me; } if (referenceHolder) { inheritedState.referencePath = ''; } else if (reference && me.isParentReference) { inheritedState.referencePath = me.referenceKey + '.'; } if (session) { inheritedState.session = session; } if (viewModel) { inheritedState.viewModelPath = ''; } else if (reference && me.isParentReference) { inheritedState.viewModelPath = me.viewModelKey + '.'; } if (layout && layout.initInheritedState) { layout.initInheritedState(inheritedState, inheritedStateInner); } }, insert: function(index, component) { var compIdx; if (component && component.isComponent) { compIdx = this.items.indexOf(component); if (compIdx !== -1) { return this.move(compIdx, index); } } return this.add(index, component); }, lookupComponent: function(comp) { if (!comp.isComponent) { if (typeof comp === 'string') { comp = Ext.ComponentManager.get(comp); } else { comp = Ext.ComponentManager.create(comp, this.defaultType); } } return comp; }, move: function(fromIdx, toIdx) { var me = this, items = me.items, item; if (fromIdx.isComponent) { fromIdx = items.indexOf(fromIdx); } item = items.getAt(fromIdx); if (fromIdx !== toIdx) { item = items.removeAt(fromIdx); if (item === false) { return false; } toIdx = Math.min(toIdx, items.getCount()); items.insert(toIdx, item); me.onMove(item, fromIdx, toIdx); if (me.hasListeners.childmove) { me.fireEvent('childmove', me, item, fromIdx, toIdx); } me.updateLayout(); } return item; }, moveBefore: function(item, before) { if (item !== before) { item = this.layout.moveItemBefore(item, before); } return item; }, moveAfter: function(item, after) { var layout = this.layout, index; if (item !== after) { index = after ? layout.getMoveAfterIndex(after) : 0; item = layout.moveItemBefore(item, this.items.getAt(index)); } return item; }, nextChild: function(child, selector) { var me = this, items = me.items, childIndex = items.indexOf(child), i = 0, len = items.length, result; if (childIndex !== -1) { if (selector) { for (; i < len; i++) { result = items.getAt(childIndex + i); if (!result || Ext.ComponentQuery.is(result, selector)) { break; } } } else { result = items.getAt(childIndex + 1); } if (!result && me.ownerCt) { result = me.ownerCt.nextChild(me, selector); } } return result; }, onAdd: Ext.emptyFn, onBeforeAdd: function(item) { var owner = item.ownerCt; if (owner && owner !== this) { owner.remove(item, false); } }, onMove: Ext.emptyFn, onRemove: Ext.emptyFn, onPosition: function() { this.callParent(arguments); this.repositionFloatingItems(); }, onResize: function() { this.callParent(arguments); this.repositionFloatingItems(); }, prevChild: function(child, selector) { var me = this, items = me.items, childIndex = items.indexOf(child), i = 0, len = items.length, result; if (childIndex !== -1) { if (selector) { for (; i < len; i++) { result = items.getAt(childIndex - i); if (!result || Ext.ComponentQuery.is(result, selector)) { break; } } } else { result = items.getAt(childIndex - 1); } if (!result && me.ownerCt) { result = me.ownerCt.nextChild(me, selector); } } return result; }, remove: function(component, autoDestroy) { var me = this, c = me.getComponent(component); if (!arguments.length) { Ext.log.warn("Ext.container.Container: remove takes an argument of the component to remove. cmp.remove() is incorrect usage."); } if (c && (!me.hasListeners.beforeremove || me.fireEvent('beforeremove', me, c) !== false)) { me.doRemove(c, autoDestroy); if (me.hasListeners.remove) { me.fireEvent('remove', me, c); } if (!me.destroying && !c.floating) { me.updateLayout(); } } return c; }, removeAll: function(autoDestroy) { var me = this, removeItems = me.items.items.slice().concat(me.floatingItems.items), items = [], i = 0, len = removeItems.length, item; Ext.suspendLayouts(); me.removingAll = true; for (; i < len; i++) { item = removeItems[i]; me.remove(item, autoDestroy); if (item.ownerCt !== me) { items.push(item); } } me.removingAll = false; Ext.resumeLayouts(!!len); return items; }, setLayout: function(layout) { var me = this, currentLayout = me.layout, currentIsLayout = currentLayout && currentLayout.isLayout, protoLayout, type; if (typeof layout === 'string') { layout = { type: layout }; } type = layout.type; if (currentIsLayout && (!type || (type === currentLayout.type))) { delete layout.type; currentLayout.setConfig(layout); } else { if (currentIsLayout) { currentLayout.setOwner(null); } protoLayout = me.self.prototype.layout; if (typeof protoLayout === 'string') { layout.type = type || protoLayout; } else { Ext.merge(Ext.merge({}, protoLayout), layout); } layout = this.layout = Ext.Factory.layout(layout); layout.setOwner(this); } if (me.rendered) { me.updateLayout(); } }, setActiveItem: function(item) { return this.getLayout().setActiveItem(item); }, privates: { applyDefaults: function(config) { var me = this, defaults = me.defaults; if (defaults) { if (Ext.isFunction(defaults)) { defaults = defaults.call(me, config); } if (Ext.isString(config)) { config = Ext.ComponentManager.get(config); } if (config.isComponent) { config.setConfig(defaults, null, me._applyDefaultsOptions); } else { config = me.getConfigurator().merge(me, Ext.Object.fork(defaults), config); } } return config; }, applyReference: function(reference) { var len; if (reference && reference.charAt(len = reference.length - 1) === '>') { this.isParentReference = true; reference = reference.substring(0, len); } if (reference && !this.validIdRe.test(reference)) { Ext.Error.raise('Invalid reference "' + reference + '" for ' + this.getId() + ' - not a valid identifier'); } return reference; }, applyTargetCls: function(targetCls) { this.layoutTargetCls = targetCls; }, attachReference: function(component) { var me = this, key, refs; if (me.destroying || me.isDestroyed) { return; } refs = me.refs || (me.refs = {}); key = component.referenceKey; if (refs[key] && refs[key] !== component) { Ext.log.warn('Duplicate reference: "' + key + '" on ' + me.id); } refs[key] = component; }, clearReference: function(component) { var refs = this.refs, key = component.referenceKey; if (refs && key) { component.viewModelKey = component.referenceKey = refs[key] = null; } }, clearReferences: function() { this.refs = null; }, detachComponent: function(component) { Ext.getDetachedBody().appendChild(component.getEl()); }, doRemove: function(component, doDestroy) { doDestroy = doDestroy === true || (doDestroy !== false && this.autoDestroy); var me = this, layout = me.layout, hasLayout = layout && me.rendered, isDestroying = component.destroying || doDestroy, floating = component.floating; if (floating) { me.floatingItems.remove(component); } else { me.items.remove(component); } if (hasLayout && !floating) { if (layout.running) { Ext.Component.cancelLayout(component, isDestroying); } layout.onRemove(component, isDestroying); } component.onRemoved(isDestroying); me.onRemove(component, isDestroying); if (doDestroy) { component.destroy(); } else { if (hasLayout && !floating) { layout.afterRemove(component); } if (me.detachOnRemove && component.rendered) { me.detachComponent(component); } } }, finishRenderChildren: function() { this.callParent(); var layout = this.getLayout(); if (layout) { layout.finishRender(); } }, getChildItemsToDisable: function() { return this.query('[isFormField],[isFocusableContainer],button'); }, getComponentId: function(comp) { return comp.getItemId && comp.getItemId(); }, getContentTarget: function() { return this.getLayout().getContentTarget(); }, getDefaultContentTarget: function() { return this.el; }, getScrollerEl: function() { return this.layout.getScrollerEl() || this.callParent(); }, prepareItems: function(items, applyDefaults) { if (Ext.isArray(items)) { items = items.slice(); } else { items = [ items ]; } var me = this, i = 0, len = items.length, item; for (; i < len; i++) { item = items[i]; if (item == null) { Ext.Array.erase(items, i, 1); --i; --len; } else { if (applyDefaults) { item = this.applyDefaults(item); } item.initOwnerCt = me; if (item.isComponent) { item.instancedCmp = true; } items[i] = me.lookupComponent(item); delete item.initOwnerCt; } } return items; }, repositionFloatingItems: function() { var floaters = this.floatingItems.items, floaterCount = floaters.length, i, floater; for (i = 0; i < floaterCount; i++) { floater = floaters[i]; if (floater.el && !floater.hidden) { floater.setPosition(floater.x, floater.y); } } }, _noMargin: { 'margin-top': '', 'margin-right': '', 'margin-bottom': '', 'margin-left': '' }, resetItemMargins: function() { var items = this.items.items, i = items.length, noMargin = this._noMargin, item; while (i--) { item = items[i]; item.margin$ = null; item.el.setStyle(noMargin); } }, setupRenderTpl: function(renderTpl) { this.callParent(arguments); this.getLayout().setupRenderTpl(renderTpl); } } }); Ext.define('Ext.layout.container.Editor', { alias: 'layout.editor', extend: 'Ext.layout.container.Container', autoSizeDefault: { width: 'field', height: 'field' }, sizePolicies: { $: { $: { readsWidth: 1, readsHeight: 1, setsWidth: 0, setsHeight: 0 }, boundEl: { readsWidth: 1, readsHeight: 0, setsWidth: 0, setsHeight: 1 } }, boundEl: { $: { readsWidth: 0, readsHeight: 1, setsWidth: 1, setsHeight: 0 }, boundEl: { readsWidth: 0, readsHeight: 0, setsWidth: 1, setsHeight: 1 } } }, getItemSizePolicy: function(item) { var me = this, autoSize = me.owner.autoSize, key = autoSize && autoSize.width, policy = me.sizePolicies; policy = policy[key] || policy.$; key = autoSize && autoSize.height; policy = policy[key] || policy.$; return policy; }, calculate: function(ownerContext) { var me = this, owner = me.owner, autoSize = owner.autoSize, fieldWidth, fieldHeight; if (autoSize === true) { autoSize = me.autoSizeDefault; } if (autoSize) { fieldWidth = me.getDimension(owner, autoSize.width, 'getWidth', owner.width); fieldHeight = me.getDimension(owner, autoSize.height, 'getHeight', owner.height); } ownerContext.childItems[0].setSize(fieldWidth, fieldHeight); ownerContext.setWidth(fieldWidth); ownerContext.setHeight(fieldHeight); ownerContext.setContentSize(fieldWidth || owner.field.getWidth(), fieldHeight || owner.field.getHeight()); }, getDimension: function(owner, type, getMethod, ownerSize) { switch (type) { case 'boundEl': return owner.boundEl[getMethod](); case 'field': return undefined; default: return ownerSize; } } }); Ext.define('Ext.Editor', { extend: 'Ext.container.Container', xtype: 'editor', requires: [ 'Ext.layout.container.Editor' ], layout: 'editor', allowBlur: true, revertInvalid: true, value: '', alignment: 'c-c?', offsets: [ 0, 0 ], shadow: 'frame', constrain: false, swallowKeys: true, completeOnEnter: true, cancelOnEsc: true, updateEl: false, focusOnToFront: false, baseCls: Ext.baseCSSPrefix + 'editor', editing: false, preventDefaultAlign: true, specialKeyDelay: 1, initComponent: function() { var me = this, field = me.field = Ext.ComponentManager.create(me.field || {}, 'textfield'); field.msgTarget = field.msgTarget || 'qtip'; me.mon(field, { scope: me, specialkey: me.onSpecialKey }); if (field.grow) { me.mon(field, 'autosize', me.onFieldAutosize, me, { delay: 1 }); } me.floating = { constrain: me.constrain }; me.items = field; me.callParent(arguments); }, onAdded: function(container) { this.ownerCmp = container; }, onFieldAutosize: function() { this.updateLayout(); }, afterRender: function(ct, position) { var me = this, field = me.field, inputEl = field.inputEl; me.callParent(arguments); if (inputEl) { inputEl.dom.name = ''; if (me.swallowKeys) { inputEl.swallowEvent([ 'keypress', 'keydown' ]); } } }, onSpecialKey: function(field, event) { var me = this, key = event.getKey(), complete = me.completeOnEnter && key === event.ENTER, cancel = me.cancelOnEsc && key === event.ESC, task = me.specialKeyTask; if (complete || cancel) { event.stopEvent(); if (!task) { me.specialKeyTask = task = new Ext.util.DelayedTask(); } task.delay(me.specialKeyDelay, complete ? me.completeEdit : me.cancelEdit, me); if (me.specialKeyDelay === 0) { task.cancel(); if (complete) { me.completeEdit(); } else { me.cancelEdit(); } } } me.fireEvent('specialkey', me, field, event); }, startEdit: function(el, value) { var me = this, field = me.field, dom, ownerCt, renderTo; me.completeEdit(); me.boundEl = Ext.get(el); dom = me.boundEl.dom; value = Ext.isDefined(value) ? value : Ext.String.trim(dom.textContent || dom.innerText || dom.innerHTML); if (me.fireEvent('beforestartedit', me, me.boundEl, value) !== false) { Ext.suspendLayouts(); if (!me.rendered) { ownerCt = me.ownerCt; renderTo = me.renderTo || (ownerCt && ownerCt.getEl()) || Ext.getBody(); Ext.fly(renderTo).position(); me.renderTo = renderTo; } me.startValue = value; me.show(); me.realign(true); field.suspendEvents(); field.setValue(value); field.resetOriginalValue(); field.resumeEvents(); field.focus(field.selectOnFocus ? true : [ Number.MAX_VALUE ]); if (field.autoSize) { field.autoSize(); } Ext.resumeLayouts(true); me.toggleBoundEl(false); me.editing = true; } }, realign: function(autoSize) { var me = this; if (autoSize === true) { me.updateLayout(); } me.alignTo(me.boundEl, me.alignment, me.offsets); }, completeEdit: function(remainVisible) { var me = this, field = me.field, startValue = me.startValue, value; if (!me.editing) { return; } if (field.assertValue) { field.assertValue(); } value = me.getValue(); if (!field.isValid()) { if (me.revertInvalid !== false) { me.cancelEdit(remainVisible); } return; } if (me.ignoreNoChange && !field.didValueChange(value, startValue)) { me.onEditComplete(remainVisible); return; } if (me.fireEvent('beforecomplete', me, value, startValue) !== false) { value = me.getValue(); if (me.updateEl && me.boundEl) { me.boundEl.setHtml(value); } me.onEditComplete(remainVisible); me.fireEvent('complete', me, value, startValue); } }, onShow: function() { var me = this; me.callParent(arguments); me.fireEvent('startedit', me, me.boundEl, me.startValue); }, cancelEdit: function(remainVisible) { var me = this, startValue = me.startValue, field = me.field, value; if (me.editing) { if (field) { value = me.editedValue = me.getValue(); field.suspendEvents(); me.setValue(startValue); field.resumeEvents(); } me.onEditComplete(remainVisible); me.fireEvent('canceledit', me, value, startValue); delete me.editedValue; } }, onEditComplete: function(remainVisible) { this.editing = false; if (remainVisible !== true) { this.hide(); this.toggleBoundEl(true); } }, onFocusLeave: function(e) { var me = this; if (me.allowBlur === true && me.editing && me.selectSameEditor !== true) { this.completeEdit(); } this.callParent([ e ]); }, onHide: function() { var me = this, field = me.field; if (me.editing) { me.completeEdit(); } else if (field.collapse) { field.collapse(); } me.callParent(arguments); }, getValue: function() { return this.field.getValue(); }, setValue: function(value) { this.field.setValue(value); }, toggleBoundEl: function(visible) { if (this.hideEl !== false) { this.boundEl.setVisible(visible); } }, beforeDestroy: function() { var me = this, task = me.specialKeyTask; if (task) { task.cancel(); } me.specialKeyTask = me.field = me.boundEl = Ext.destroy(me.field); me.callParent(arguments); } }); Ext.define('Ext.EventManager', { singleton: true, mouseLeaveRe: /(mouseout|mouseleave)/, mouseEnterRe: /(mouseover|mouseenter)/, addListener: function(element, eventName, fn, scope, options) { Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.dom.Element#addListener to attach an event listener."); Ext.get(element).addListener(eventName, fn, scope, options); }, onWindowResize: function(fn, scope, options) { Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.on('resize', fn) to attach a window resize listener."); Ext.GlobalEvents.on('resize', fn, scope, options); }, onWindowUnload: function(fn, scope, options) { Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.getWin().on('unload', fn) to attach a window unload listener."); Ext.getWin().on('unload', fn, scope, options); }, purgeElement: function(element, eventName) { Ext.log.warn("Ext.EventManager is deprecated. " + "Call clearListeners() on a Ext.dom.Element to remove all listeners."); Ext.get(element).clearListeners(); }, removeAll: function(element) { Ext.log.warn("Ext.EventManager is deprecated. " + "Call clearListeners() on a Ext.dom.Element to remove all listeners."); Ext.get(element).clearListeners(); }, removeListener: function(element, eventName, fn, scope, options) { Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.dom.Element#removeListener to remove an event listener."); Ext.get(element).removeListener(eventName, fn, scope, options); }, removeResizeListener: function(fn, scope) { Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.on('resize', fn) to detach a window resize listener."); Ext.GlobalEvents.un('resize', fn, scope); }, removeUnloadListener: function(fn, scope) { Ext.log.warn("Ext.EventManager is deprecated. " + "Use Ext.getWin().un('unload', fn) to detach a window unload listener."); Ext.getWin().un('unload', fn, scope); }, stopEvent: function(event) { Ext.log.warn("Ext.EventManager.stopEvent() is deprecated. " + "Call stopEvent() directly on the Ext.event.Event instance instead."); this.stopPropagation(event); this.preventDefault(event); }, stopPropagation: function(event) { Ext.log.warn("Ext.EventManager.stopPropagation() is deprecated. " + "Call stopPropagation() directly on the Ext.event.Event instance instead."); event = event.browserEvent || event; if (event.stopPropagation) { event.stopPropagation(); } else { event.cancelBubble = true; } }, preventDefault: function(event) { Ext.log.warn("Ext.EventManager.preventDefault() is deprecated. " + "Call preventDefault() directly on the Ext.event.Event instance instead."); 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) {} } }, getId: function(element) { Ext.log.warn("Ext.EventManager.getId() is deprecated. " + "Call Ext.get() to assign ids to elements."); element = Ext.get(element); return element.id; }, getRelatedTarget: function(event) { Ext.log.warn("Ext.EventManager.getRelatedTarget() is deprecated. " + "Call getRelatedTarget() directly on the Ext.event.Event instance instead."); 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) { Ext.log.warn("Ext.EventManager.getPageX() is deprecated. " + "Call getX() directly on the Ext.event.Event instance instead."); return this.getPageXY(event)[0]; }, getPageXY: function(event) { Ext.log.warn("Ext.EventManager.getPageXY() is deprecated. " + "Call getXY() directly on the Ext.event.Event instance instead."); event = event.browserEvent || event; var x = event.pageX, y = event.pageY, docEl = document.documentElement, body = document.body; if (!x && x !== 0) { x = event.clientX + (docEl && docEl.scrollLeft || body && body.scrollLeft || 0) - (docEl && docEl.clientLeft || body && body.clientLeft || 0); y = event.clientY + (docEl && docEl.scrollTop || body && body.scrollTop || 0) - (docEl && docEl.clientTop || body && body.clientTop || 0); } return [ x, y ]; }, getPageY: function(event) { Ext.log.warn("Ext.EventManager.getPageY() is deprecated. " + "Call getY() directly on the Ext.event.Event instance instead."); return this.getPageXY(event)[1]; }, getTarget: function(event) { Ext.log.warn("Ext.EventManager.getTarget() is deprecated. " + "Call getTarget() directly on the Ext.event.Event instance instead."); event = event.browserEvent || event; return Ext.EventManager.resolveTextNode(event.target || event.srcElement); }, resolveTextNode: Ext.isGecko ? function(node) { if (node) { var s = HTMLElement.prototype.toString.call(node); if (s !== '[xpconnect wrapped native prototype]' && s !== '[object XULElement]') { return node.nodeType === 3 ? node.parentNode : node; } } } : function(node) { return node && node.nodeType === 3 ? node.parentNode : node; } }, function(EventManager) { EventManager.on = EventManager.addListener; EventManager.un = EventManager.removeListener; }); Ext.define('Ext.FocusManager', { singleton: true, alternateClassName: [ 'Ext.FocusMgr' ], enabled: true, enable: Ext.emptyFn, disable: Ext.emptyFn }); Ext.define('Ext.Img', { extend: 'Ext.Component', alias: [ 'widget.image', 'widget.imagecomponent' ], autoEl: 'img', baseCls: Ext.baseCSSPrefix + 'img', src: '', alt: '', title: '', imgCls: '', ariaRole: 'img', maskOnDisable: false, initComponent: function() { if (this.glyph) { this.autoEl = 'div'; } this.callParent(); }, getElConfig: function() { var me = this, autoEl = me.autoEl, config = me.callParent(), glyphFontFamily = Ext._glyphFontFamily, glyph = me.glyph, img, glyphParts; if (autoEl === 'img' || (Ext.isObject(autoEl) && autoEl.tag === 'img')) { img = config; } else if (me.glyph) { if (typeof glyph === 'string') { glyphParts = glyph.split('@'); glyph = glyphParts[0]; glyphFontFamily = glyphParts[1] || glyphFontFamily; } config.html = '&#' + glyph + ';'; if (glyphFontFamily) { config.style = config.style || {}; config.style.fontFamily = glyphFontFamily; } } else { config.cn = [ img = { tag: 'img', role: me.ariaRole, id: me.id + '-img' } ]; } if (img) { if (me.imgCls) { img.cls = (img.cls ? img.cls + ' ' : '') + me.imgCls; } img.src = me.src || Ext.BLANK_IMAGE_URL; } if (me.alt) { (img || config).alt = me.alt; } if (me.title) { (img || config).title = me.title; } return config; }, onRender: function() { var me = this, autoEl = me.autoEl, el; me.callParent(arguments); el = me.el; if (autoEl === 'img' || (Ext.isObject(autoEl) && autoEl.tag === 'img')) { me.imgEl = el; } else { me.imgEl = el.getById(me.id + '-img'); } }, onDestroy: function() { var me = this, imgEl = me.imgEl; if (imgEl && me.el !== imgEl) { imgEl.destroy(); } this.imgEl = null; this.callParent(); }, setSrc: function(src) { var me = this, imgEl = me.imgEl; me.src = src; if (imgEl) { imgEl.dom.src = src || Ext.BLANK_IMAGE_URL; } }, setGlyph: function(glyph) { var me = this, glyphFontFamily = Ext._glyphFontFamily, old = me.glyph, el = me.el, glyphParts; me.glyph = glyph; if (me.rendered && glyph !== old) { if (typeof glyph === 'string') { glyphParts = glyph.split('@'); glyph = glyphParts[0]; glyphFontFamily = glyphParts[1] || glyphFontFamily; } el.dom.innerHTML = '&#' + glyph + ';'; if (glyphFontFamily) { el.setStyle('font-family', glyphFontFamily); } } } }); Ext.define('Ext.util.StoreHolder', { requires: [ 'Ext.data.StoreManager' ], mixinId: 'storeholder', bindStore: function(store, initial, propertyName) { propertyName = propertyName || 'store'; var me = this, oldStore = initial ? null : me[propertyName]; if (store !== oldStore) { if (oldStore) { me.onUnbindStore(oldStore, initial, propertyName); if (me.isComponent && propertyName === 'store' && oldStore.autoDestroy) { oldStore.destroy(); } else { me.unbindStoreListeners(oldStore); } } if (store) { me[propertyName] = store = Ext.data.StoreManager.lookup(store); me.bindStoreListeners(store); me.onBindStore(store, initial, propertyName, oldStore); } else { me[propertyName] = null; } } return me; }, getStore: function() { return this.store; }, setStore: function(store) { this.bindStore(store); }, unbindStoreListeners: function(store) { var listeners = this.storeListeners; if (listeners) { store.un(listeners); } }, bindStoreListeners: function(store) { var listeners = this.getStoreListeners(store); if (listeners) { listeners = Ext.apply({}, listeners); if (!listeners.scope) { listeners.scope = this; } this.storeListeners = listeners; store.on(listeners); } }, getStoreListeners: Ext.emptyFn, onUnbindStore: Ext.emptyFn, onBindStore: Ext.emptyFn }); Ext.define('Ext.LoadMask', { extend: 'Ext.Component', alias: 'widget.loadmask', mixins: [ 'Ext.util.StoreHolder' ], uses: [ 'Ext.data.StoreManager' ], isLoadMask: true, msg: 'Loading...', msgCls: Ext.baseCSSPrefix + 'mask-loading', msgWrapCls: Ext.baseCSSPrefix + 'mask-msg', useMsg: true, useTargetEl: false, cls: Ext.baseCSSPrefix + 'mask', componentCls: Ext.baseCSSPrefix + 'border-box', ariaRole: 'status', focusable: true, tabIndex: 0, autoEl: { tag: 'div', role: 'status' }, childEls: [ 'msgWrapEl', 'msgEl', 'msgTextEl' ], renderTpl: [ '
', '
', '
{msg}
', '
', '
' ], constructor: function(config) { var me = this, comp; if (arguments.length === 2) { if (Ext.isDefined(Ext.global.console)) { Ext.global.console.warn('Ext.LoadMask: LoadMask now uses a standard 1 arg constructor: use the target config'); } comp = me.target = config; config = arguments[1]; } else { comp = config.target; } if (config.maskCls) { Ext.log.warn('Ext.LoadMask property maskCls is deprecated, use msgWrapCls instead'); config.msgWrapCls = config.msgWrapCls || config.maskCls; } me.callParent([ config ]); if (comp.isComponent) { me.ownerCt = comp; me.hidden = true; me.renderTo = me.getMaskTarget(); me.external = me.renderTo === Ext.getBody(); me.bindComponent(comp); } else { if (Ext.isDefined(Ext.global.console)) { Ext.global.console.warn('Ext.LoadMask: LoadMask for elements has been deprecated, use Ext.dom.Element.mask & Ext.dom.Element.unmask'); } comp = Ext.get(comp); me.isElement = true; me.renderTo = me.target; } me.render(me.renderTo); if (me.store) { me.bindStore(me.store, true); } }, initRenderData: function() { var result = this.callParent(arguments); result.msg = this.msg || ''; return result; }, onRender: function() { this.callParent(arguments); this.maskEl = this.el; }, bindComponent: function(comp) { var me = this, listeners = { scope: this, resize: me.sizeMask }; if (me.external) { listeners.added = me.onComponentAdded; listeners.removed = me.onComponentRemoved; if (comp.floating) { listeners.move = me.sizeMask; me.activeOwner = comp; } else if (comp.ownerCt) { me.onComponentAdded(comp.ownerCt); } } me.mon(comp, listeners); if (me.external) { me.mon(Ext.GlobalEvents, { show: me.onContainerShow, hide: me.onContainerHide, expand: me.onContainerExpand, collapse: me.onContainerCollapse, scope: me }); } }, onComponentAdded: function(owner) { var me = this; delete me.activeOwner; me.floatParent = owner; if (!owner.floating) { owner = owner.up('[floating]'); } if (owner) { me.activeOwner = owner; me.mon(owner, 'move', me.sizeMask, me); me.mon(owner, 'tofront', me.onOwnerToFront, me); } else { me.preventBringToFront = true; } owner = me.floatParent.ownerCt; if (me.rendered && me.isVisible() && owner) { me.floatOwner = owner; me.mon(owner, 'afterlayout', me.sizeMask, me, { single: true }); } }, onComponentRemoved: function(owner) { var me = this, activeOwner = me.activeOwner, floatOwner = me.floatOwner; if (activeOwner) { me.mun(activeOwner, 'move', me.sizeMask, me); me.mun(activeOwner, 'tofront', me.onOwnerToFront, me); } if (floatOwner) { me.mun(floatOwner, 'afterlayout', me.sizeMask, me); } delete me.activeOwner; delete me.floatOwner; }, afterRender: function() { var me = this; me.callParent(arguments); if (Ext.isIE) { me.el.on('mousedown', me.onMouseDown, me); } this.el.skipGarbageCollection = true; }, onMouseDown: function(e) { var el = this.el; if (e.within(el)) { e.preventDefault(); el.focus(); } }, onOwnerToFront: function(owner, zIndex) { this.el.setStyle('zIndex', zIndex + 1); }, onContainerShow: function(container) { if (!this.isHierarchicallyHidden()) { this.onComponentShow(); } }, onContainerHide: function(container) { if (this.isHierarchicallyHidden()) { this.onComponentHide(); } }, onContainerExpand: function(container) { if (!this.isHierarchicallyHidden()) { this.onComponentShow(); } }, onContainerCollapse: function(container) { if (this.isHierarchicallyHidden()) { this.onComponentHide(); } }, onComponentHide: function() { var me = this; if (me.rendered && me.isVisible()) { me.hide(); me.showNext = true; } }, onComponentShow: function() { if (this.showNext) { this.show(); } delete this.showNext; }, sizeMask: function() { var me = this, target = me.activeOwner || me.target, boxTarget = me.external ? me.getOwner().el : me.getMaskTarget(); if (me.rendered && me.isVisible()) { if (me.external) { if (!me.isElement && target.floating) { me.onOwnerToFront(target, target.el.getZIndex()); } me.el.setSize(boxTarget.getSize()).alignTo(boxTarget, 'tl-tl'); } me.msgWrapEl.center(me.el); } }, bindStore: function(store, initial) { var me = this; me.mixins.storeholder.bindStore.apply(me, arguments); store = me.store; if (store && store.isLoading()) { me.onBeforeLoad(); } }, getStoreListeners: function(store) { var load = this.onLoad, beforeLoad = this.onBeforeLoad, result = { cachemiss: beforeLoad, cachefilled: { fn: load, buffer: 100 } }; if (!store.loadsSynchronously()) { result.beforeload = beforeLoad; result.load = load; } return result; }, onDisable: function() { this.callParent(arguments); if (this.loading) { this.onLoad(); } }, getOwner: function() { return this.ownerCt || this.ownerCmp || this.floatParent; }, getMaskTarget: function() { var owner = this.getOwner(); if (this.isElement) { return this.target; } return this.useTargetEl ? owner.getTargetEl() : (owner.getMaskTarget() || Ext.getBody()); }, onBeforeLoad: function() { var me = this, owner = me.getOwner(), origin; if (!me.disabled) { me.loading = true; if (owner.componentLayoutCounter) { me.maybeShow(); } else { origin = owner.afterComponentLayout; owner.afterComponentLayout = function() { owner.afterComponentLayout = origin; origin.apply(owner, arguments); me.maybeShow(); }; } } }, maybeShow: function() { var me = this, owner = me.getOwner(); if (!owner.isVisible(true)) { me.showNext = true; } else if (me.loading && owner.rendered) { me.show(); } }, hide: function() { var me = this, ownerCt = me.ownerCt; if (me.isElement) { ownerCt.unmask(); me.fireEvent('hide', this); return; } ownerCt.enableTabbing(); ownerCt.setMasked(false); delete me.showNext; return me.callParent(arguments); }, show: function() { var me = this; if (me.isElement) { me.ownerCt.mask(this.useMsg ? this.msg : '', this.msgCls); me.fireEvent('show', this); return; } return me.callParent(arguments); }, afterShow: function() { var me = this, ownerCt = me.ownerCt, el = me.el; me.loading = true; me.callParent(arguments); if (me.hasOwnProperty('msgWrapCls')) { el.dom.className = me.msgWrapCls; } if (me.useMsg) { me.msgTextEl.setHtml(me.msg); } else { me.msgEl.hide(); } if (me.shim || Ext.useShims) { el.enableShim(null, true); } else { el.disableShim(); } ownerCt.disableTabbing(); ownerCt.setMasked(true); el.restoreTabbableState(); if (ownerCt.containsFocus) { me.focus(); } me.sizeMask(); }, onLoad: function() { this.loading = false; this.hide(); }, beforeDestroy: function() { this.ownerCt = null; this.bindStore(null); this.callParent(); }, onDestroy: function() { var me = this; if (me.isElement) { me.ownerCt.unmask(); } me.callParent(); }, privates: { getFocusEl: function() { return this.el; } } }); Ext.define('Ext.layout.component.Component', { extend: 'Ext.layout.Layout', type: 'component', isComponentLayout: true, nullBox: {}, usesContentHeight: true, usesContentWidth: true, usesHeight: true, usesWidth: true, widthCache: {}, heightCache: {}, beginLayoutCycle: function(ownerContext, firstCycle) { var me = this, owner = me.owner, ownerCtContext = ownerContext.ownerCtContext, heightModel = ownerContext.heightModel, widthModel = ownerContext.widthModel, body = owner.el.dom === document.body, lastBox = owner.lastBox || me.nullBox, lastSize = owner.el.lastBox || me.nullBox, dirty = !body, isTopLevel = ownerContext.isTopLevel, ownerLayout, v, width, height; me.callParent([ ownerContext, firstCycle ]); if (firstCycle) { if (me.usesContentWidth) { ++ownerContext.consumersContentWidth; } if (me.usesContentHeight) { ++ownerContext.consumersContentHeight; } if (me.usesWidth) { ++ownerContext.consumersWidth; } if (me.usesHeight) { ++ownerContext.consumersHeight; } if (ownerCtContext && !ownerCtContext.hasRawContent) { ownerLayout = owner.ownerLayout; if (ownerLayout) { if (ownerLayout.usesWidth) { ++ownerContext.consumersWidth; } if (ownerLayout.usesHeight) { ++ownerContext.consumersHeight; } } } } if (widthModel.configured) { width = owner[widthModel.names.width]; if (isTopLevel && widthModel.calculatedFrom) { width = lastBox.width; } if (!body) { dirty = me.setWidthInDom || (firstCycle ? width !== lastSize.width : widthModel.constrained); } ownerContext.setWidth(width, dirty); } else if (isTopLevel) { if (widthModel.calculated) { v = lastBox.width; ownerContext.setWidth(v, v !== lastSize.width); } v = lastBox.x; ownerContext.setProp('x', v, v !== lastSize.x); } if (heightModel.configured) { height = owner[heightModel.names.height]; if (isTopLevel && heightModel.calculatedFrom) { height = lastBox.height; } if (!body) { dirty = firstCycle ? height !== lastSize.height : heightModel.constrained; } ownerContext.setHeight(height, dirty); } else if (isTopLevel) { if (heightModel.calculated) { v = lastBox.height; ownerContext.setHeight(v, v !== lastSize.height); } v = lastBox.y; ownerContext.setProp('y', v, v !== lastSize.y); } }, finishedLayout: function(ownerContext) { var me = this, elementChildren = ownerContext.children, owner = me.owner, len, i, elContext, lastBox, props; if (elementChildren) { len = elementChildren.length; for (i = 0; i < len; i++) { elContext = elementChildren[i]; elContext.el.lastBox = elContext.props; } } ownerContext.previousSize = me.lastComponentSize; me.lastComponentSize = owner.el.lastBox = props = ownerContext.props; lastBox = owner.lastBox || (owner.lastBox = {}); lastBox.x = props.x; lastBox.y = props.y; lastBox.width = props.width; lastBox.height = props.height; lastBox.invalid = false; me.callParent([ ownerContext ]); }, notifyOwner: function(ownerContext) { var me = this, currentSize = me.lastComponentSize, prevSize = ownerContext.previousSize, args = [ currentSize.width, currentSize.height, undefined, undefined ]; if (prevSize) { args[2] = prevSize.width; args[3] = prevSize.height; } me.owner.afterComponentLayout.apply(me.owner, args); }, getTarget: function() { return this.owner.el; }, getRenderTarget: function() { return this.owner.el; }, cacheTargetInfo: function(ownerContext) { var me = this, targetInfo = me.targetInfo, target; if (!targetInfo) { target = ownerContext.getEl('getTarget', me); me.targetInfo = targetInfo = { padding: target.getPaddingInfo(), border: target.getBorderInfo() }; } return targetInfo; }, measureAutoDimensions: function(ownerContext, dimensions) { var me = this, owner = me.owner, containerLayout = owner.layout, heightModel = ownerContext.heightModel, widthModel = ownerContext.widthModel, boxParent = ownerContext.boxParent, isBoxParent = ownerContext.isBoxParent, target = ownerContext.target, props = ownerContext.props, isContainer, ret = { gotWidth: false, gotHeight: false, isContainer: (isContainer = !ownerContext.hasRawContent) }, hv = dimensions || 3, zeroWidth, zeroHeight, needed = 0, got = 0, ready, size, temp, key, cache; if (widthModel.shrinkWrap && ownerContext.consumersContentWidth) { ++needed; zeroWidth = !(hv & 1); if (isContainer) { if (zeroWidth) { ret.contentWidth = 0; ret.gotWidth = true; ++got; } else if ((ret.contentWidth = ownerContext.getProp('contentWidth')) !== undefined) { ret.gotWidth = true; ++got; } } else { size = props.contentWidth; if (typeof size === 'number') { ret.contentWidth = size; ret.gotWidth = true; ++got; } else { if (zeroWidth) { ready = true; } else if (!ownerContext.hasDomProp('containerChildrenSizeDone')) { ready = false; } else if (isBoxParent || !boxParent || boxParent.widthModel.shrinkWrap) { ready = true; } else { ready = boxParent.hasDomProp('width'); } if (ready) { if (zeroWidth) { temp = 0; } else if (containerLayout && containerLayout.measureContentWidth) { temp = containerLayout.measureContentWidth(ownerContext); } else { if (target.cacheWidth) { key = target.xtype + '-' + target.ui; cache = me.widthCache; temp = cache[key] || (cache[key] = me.measureContentWidth(ownerContext)); } else { temp = me.measureContentWidth(ownerContext); } } if (!isNaN(ret.contentWidth = temp)) { ownerContext.setContentWidth(temp, true); ret.gotWidth = true; ++got; } } } } } else if (widthModel.natural && ownerContext.consumersWidth) { ++needed; size = props.width; if (typeof size === 'number') { ret.width = size; ret.gotWidth = true; ++got; } else { if (isBoxParent || !boxParent) { ready = true; } else { ready = boxParent.hasDomProp('width'); } if (ready) { if (!isNaN(ret.width = me.measureOwnerWidth(ownerContext))) { ownerContext.setWidth(ret.width, false); ret.gotWidth = true; ++got; } } } } if (heightModel.shrinkWrap && ownerContext.consumersContentHeight) { ++needed; zeroHeight = !(hv & 2); if (isContainer) { if (zeroHeight) { ret.contentHeight = 0; ret.gotHeight = true; ++got; } else if ((ret.contentHeight = ownerContext.getProp('contentHeight')) !== undefined) { ret.gotHeight = true; ++got; } } else { size = props.contentHeight; if (typeof size === 'number') { ret.contentHeight = size; ret.gotHeight = true; ++got; } else { if (zeroHeight) { ready = true; } else if (!ownerContext.hasDomProp('containerChildrenSizeDone')) { ready = false; } else if (owner.noWrap) { ready = true; } else if (!widthModel.shrinkWrap) { ready = (ownerContext.bodyContext || ownerContext).hasDomProp('width'); } else if (isBoxParent || !boxParent || boxParent.widthModel.shrinkWrap) { ready = true; } else { ready = boxParent.hasDomProp('width'); } if (ready) { if (zeroHeight) { temp = 0; } else if (containerLayout && containerLayout.measureContentHeight) { temp = containerLayout.measureContentHeight(ownerContext); } else { if (target.cacheHeight) { key = target.xtype + '-' + target.ui; cache = me.heightCache; temp = cache[key] || (cache[key] = me.measureContentHeight(ownerContext)); } else { temp = me.measureContentHeight(ownerContext); } } if (!isNaN(ret.contentHeight = temp)) { ownerContext.setContentHeight(temp, true); ret.gotHeight = true; ++got; } } } } } else if (heightModel.natural && ownerContext.consumersHeight) { ++needed; size = props.height; if (typeof size === 'number') { ret.height = size; ret.gotHeight = true; ++got; } else { if (isBoxParent || !boxParent) { ready = true; } else { ready = boxParent.hasDomProp('width'); } if (ready) { if (!isNaN(ret.height = me.measureOwnerHeight(ownerContext))) { ownerContext.setHeight(ret.height, false); ret.gotHeight = true; ++got; } } } } if (boxParent) { ownerContext.onBoxMeasured(); } ret.gotAll = got === needed; return ret; }, measureContentWidth: function(ownerContext) { return ownerContext.el.getWidth() - ownerContext.getFrameInfo().width; }, measureContentHeight: function(ownerContext) { return ownerContext.el.getHeight() - ownerContext.getFrameInfo().height; }, measureOwnerHeight: function(ownerContext) { return ownerContext.el.getHeight(); }, measureOwnerWidth: function(ownerContext) { return ownerContext.el.getWidth(); } }); Ext.define('Ext.layout.component.Auto', { alias: 'layout.autocomponent', extend: 'Ext.layout.component.Component', type: 'autocomponent', setHeightInDom: false, setWidthInDom: false, waitForOuterHeightInDom: false, waitForOuterWidthInDom: false, beginLayoutCycle: function(ownerContext, firstCycle) { var me = this, lastWidthModel = me.lastWidthModel, lastHeightModel = me.lastHeightModel, el = me.owner.el; me.callParent(arguments); if (lastWidthModel && lastWidthModel.fixed && ownerContext.widthModel.shrinkWrap) { el.setWidth(null); } if (lastHeightModel && lastHeightModel.fixed && ownerContext.heightModel.shrinkWrap) { el.setHeight(null); } }, calculate: function(ownerContext) { var me = this, measurement = me.measureAutoDimensions(ownerContext), heightModel = ownerContext.heightModel, widthModel = ownerContext.widthModel, width, height; if (measurement.gotWidth) { if (widthModel.shrinkWrap) { me.publishOwnerWidth(ownerContext, measurement.contentWidth); } else if (me.publishInnerWidth) { me.publishInnerWidth(ownerContext, measurement.width); } } else if (!widthModel.auto && me.publishInnerWidth) { width = me.waitForOuterWidthInDom ? ownerContext.getDomProp('width') : ownerContext.getProp('width'); if (width === undefined) { me.done = false; } else { me.publishInnerWidth(ownerContext, width); } } if (measurement.gotHeight) { if (heightModel.shrinkWrap) { me.publishOwnerHeight(ownerContext, measurement.contentHeight); } else if (me.publishInnerHeight) { me.publishInnerHeight(ownerContext, measurement.height); } } else if (!heightModel.auto && me.publishInnerHeight) { height = me.waitForOuterHeightInDom ? ownerContext.getDomProp('height') : ownerContext.getProp('height'); if (height === undefined) { me.done = false; } else { me.publishInnerHeight(ownerContext, height); } } if (!measurement.gotAll) { me.done = false; } }, calculateOwnerHeightFromContentHeight: function(ownerContext, contentHeight) { return contentHeight + ownerContext.getFrameInfo().height; }, calculateOwnerWidthFromContentWidth: function(ownerContext, contentWidth) { return contentWidth + ownerContext.getFrameInfo().width; }, publishOwnerHeight: function(ownerContext, contentHeight) { var me = this, owner = me.owner, height = me.calculateOwnerHeightFromContentHeight(ownerContext, contentHeight), constrainedHeight, dirty, heightModel; if (isNaN(height)) { me.done = false; } else { constrainedHeight = Ext.Number.constrain(height, owner.minHeight, owner.maxHeight); if (constrainedHeight === height) { dirty = me.setHeightInDom; } else { heightModel = me.sizeModels[(constrainedHeight < height) ? 'constrainedMax' : 'constrainedMin']; height = constrainedHeight; if (ownerContext.heightModel.calculatedFromShrinkWrap) { ownerContext.heightModel = heightModel; } else { ownerContext.invalidate({ heightModel: heightModel }); } } ownerContext.setHeight(height, dirty); } }, publishOwnerWidth: function(ownerContext, contentWidth) { var me = this, owner = me.owner, width = me.calculateOwnerWidthFromContentWidth(ownerContext, contentWidth), constrainedWidth, dirty, widthModel; if (isNaN(width)) { me.done = false; } else { constrainedWidth = Ext.Number.constrain(width, owner.minWidth, owner.maxWidth); if (constrainedWidth === width) { dirty = me.setWidthInDom; } else { widthModel = me.sizeModels[(constrainedWidth < width) ? 'constrainedMax' : 'constrainedMin']; width = constrainedWidth; if (ownerContext.widthModel.calculatedFromShrinkWrap) { ownerContext.widthModel = widthModel; } else { ownerContext.invalidate({ widthModel: widthModel }); } } ownerContext.setWidth(width, dirty); } } }); Ext.define('Ext.layout.component.ProgressBar', { alias: [ 'layout.progressbar' ], extend: 'Ext.layout.component.Auto', type: 'progressbar', beginLayout: function(ownerContext) { var me = this, i, textEls; me.callParent(arguments); if (!ownerContext.textEls) { textEls = me.owner.textEl; if (textEls.isComposite) { ownerContext.textEls = []; textEls = textEls.elements; for (i = textEls.length; i--; ) { ownerContext.textEls[i] = ownerContext.getEl(Ext.get(textEls[i])); } } else { ownerContext.textEls = [ ownerContext.getEl('textEl') ]; } } }, calculate: function(ownerContext) { var me = this, i, textEls, width; me.callParent(arguments); if (Ext.isNumber(width = ownerContext.getProp('width'))) { width -= ownerContext.getBorderInfo().width; textEls = ownerContext.textEls; for (i = textEls.length; i--; ) { textEls[i].setWidth(width); } } else { me.done = false; } } }); Ext.define('Ext.ProgressBar', { extend: 'Ext.Component', alias: 'widget.progressbar', requires: [ 'Ext.Template', 'Ext.CompositeElement', 'Ext.TaskManager', 'Ext.layout.component.ProgressBar' ], uses: [ 'Ext.fx.Anim' ], config: { value: 0, textTpl: null }, baseCls: Ext.baseCSSPrefix + 'progress', animate: false, text: '', waitTimer: null, childEls: [ 'bar' ], defaultBindProperty: 'value', renderTpl: [ '', '
{text}
', '
', '' ], componentLayout: 'progressbar', ariaRole: 'progressbar', initRenderData: function() { var me = this, value = me.value || 0; return Ext.apply(me.callParent(), { internalText: !me.hasOwnProperty('textEl'), text: me.text || ' ', percentage: value * 100 }); }, onRender: function() { var me = this; me.callParent(arguments); if (me.textEl) { me.textEl = Ext.get(me.textEl); me.updateText(me.text); } else { me.textEl = me.el.select('.' + me.baseCls + '-text'); } }, applyValue: function(value) { return value || 0; }, updateValue: function(value) { this.updateProgress(value, Math.round(value * 100) + '%'); }, updateProgress: function(value, text, animate) { value = value || 0; var me = this, oldValue = me.value, textTpl = me.getTextTpl(); me.value = value || (value = 0); if (text != null) { me.updateText(text); } else if (textTpl) { me.updateText(textTpl.apply({ value: value, percent: value * 100 })); } if (me.rendered && !me.isDestroyed) { if (animate === true || (animate !== false && me.animate)) { me.bar.stopAnimation(); me.bar.animate(Ext.apply({ from: { width: (oldValue * 100) + '%' }, to: { width: (value * 100) + '%' } }, me.animate)); } else { me.bar.setStyle('width', (value * 100) + '%'); } } me.fireEvent('update', me, value, text); return me; }, updateText: function(text) { var me = this; me.text = text; if (me.rendered) { me.textEl.setHtml(me.text); } return me; }, applyTextTpl: function(textTpl) { if (!textTpl.isTemplate) { textTpl = new Ext.XTemplate(textTpl); } return textTpl; }, applyText: function(text) { this.updateText(text); }, getText: function() { return this.text; }, wait: function(o) { var me = this, scope; if (!me.waitTimer) { scope = me; o = o || {}; me.updateText(o.text); me.waitTimer = Ext.TaskManager.start({ run: function(i) { var inc = o.increment || 10; i -= 1; me.updateProgress(((((i + inc) % inc) + 1) * (100 / inc)) * 0.01, null, o.animate); }, interval: o.interval || 1000, duration: o.duration, onStop: function() { if (o.fn) { o.fn.apply(o.scope || me); } me.reset(); }, scope: scope }); } return me; }, isWaiting: function() { return this.waitTimer !== null; }, reset: function(hide) { var me = this; me.updateProgress(0); me.clearTimer(); if (hide === true) { me.hide(); } return me; }, clearTimer: function() { var me = this; if (me.waitTimer) { me.waitTimer.onStop = null; Ext.TaskManager.stop(me.waitTimer); me.waitTimer = null; } }, onDestroy: function() { var me = this, bar = me.bar; me.clearTimer(); if (me.rendered) { if (me.textEl.isComposite) { me.textEl.clear(); } Ext.destroyMembers(me, 'textEl', 'progressBar'); if (bar && me.animate) { bar.stopAnimation(); } } me.callParent(); } }); Ext.define('Ext.ProgressBarWidget', { extend: 'Ext.Widget', alias: 'widget.progressbarwidget', requires: [ 'Ext.ProgressBar' ], config: { text: null, value: 0, animate: false, textTpl: null }, cachedConfig: { baseCls: Ext.baseCSSPrefix + 'progress', textCls: Ext.baseCSSPrefix + 'progress-text', ui: 'default' }, template: [ { reference: 'backgroundEl' }, { reference: 'barEl', children: [ { reference: 'textEl' } ] } ], defaultBindProperty: 'value', doSetWidth: function(width) { var me = this; me.callParent([ width ]); width -= me.element.getBorderWidth('lr'); me.backgroundEl.setWidth(width); me.textEl.setWidth(width); }, updateUi: function(ui, oldUi) { var element = this.element, barEl = this.barEl, baseCls = this.getBaseCls() + '-'; if (oldUi) { element.removeCls(baseCls + oldUi); barEl.removeCls(baseCls + 'bar-' + oldUi); } element.addCls(baseCls + ui); barEl.addCls(baseCls + 'bar-' + ui); }, updateBaseCls: function(baseCls, oldBaseCls) { if (oldBaseCls) { Ext.Error.raise('You cannot configure baseCls - use a subclass'); } this.element.addCls(baseCls); this.barEl.addCls(baseCls + '-bar'); }, updateTextCls: function(textCls) { this.backgroundEl.addCls(textCls + ' ' + textCls + '-back'); this.textEl.addCls(textCls); }, applyValue: function(value) { return value || 0; }, updateValue: function(value, oldValue) { var me = this, barEl = me.barEl, textTpl = me.getTextTpl(); if (textTpl) { me.setText(textTpl.apply({ value: value, percent: Math.round(value * 100) })); } if (me.getAnimate()) { barEl.stopAnimation(); barEl.animate(Ext.apply({ from: { width: (oldValue * 100) + '%' }, to: { width: (value * 100) + '%' } }, me.animate)); } else { barEl.setStyle('width', (value * 100) + '%'); } }, updateText: function(text) { this.backgroundEl.setHtml(text); this.textEl.setHtml(text); }, applyTextTpl: function(textTpl) { if (!textTpl.isTemplate) { textTpl = new Ext.XTemplate(textTpl); } return textTpl; } }); Ext.define('Ext.panel.Bar', { extend: 'Ext.container.Container', vertical: false, _verticalSides: { left: 1, right: 1 }, initComponent: function() { var me = this, vertical = me.vertical; me.dock = me.dock || (vertical ? 'left' : 'top'); me.layout = Ext.apply(vertical ? { type: 'vbox', align: 'middle', alignRoundingMethod: 'ceil' } : { type: 'hbox', align: 'middle', alignRoundingMethod: 'floor' }, me.layout); this.callParent(); }, onAdded: function(container, pos, instanced) { this.initOrientation(); this.callParent([ container, pos, instanced ]); }, onRemoved: function(destroying) { this.removeClsWithUI(this.uiCls); this.callParent([ destroying ]); }, beforeRender: function() { var me = this; if (me.forceOrientation || !me.ownerCt) { me.initOrientation(); } me.callParent(); }, setDock: function(dock) { var me = this, layout, vertical; if (dock !== me.dock) { Ext.suspendLayouts(); me.clearOrientation(); me.callParent([ dock ]); me.initOrientation(); vertical = me.vertical; layout = me.layout; layout.setVertical(vertical); layout.setAlignRoundingMethod(vertical ? 'ceil' : 'floor'); Ext.resumeLayouts(true); } }, privates: { clearOrientation: function() { this.removeClsWithUI([ this.vertical ? 'vertical' : 'horizontal', this.getDockName() ]); }, getDockName: function() { return this.dock; }, initOrientation: function() { var me = this, dock = me.dock, vertical = (me.vertical = (dock ? dock in me._verticalSides : me.vertical)); me.addClsWithUI([ vertical ? 'vertical' : 'horizontal', me.getDockName() ]); } } }); Ext.define('Ext.panel.Title', { extend: 'Ext.Component', xtype: 'title', isTitle: true, noWrap: true, textAlign: 'left', iconAlign: 'left', rotation: 0, text: ' ', beforeRenderConfig: { textAlign: null, text: null, glyph: null, icon: null, iconAlign: null, iconCls: null, rotation: null }, autoEl: { unselectable: 'on' }, childEls: [ 'textEl', 'iconEl', 'iconWrapEl' ], renderTpl: '{iconMarkup}' + '
' + ' role="{headerRole}"' + '' + '>{text}
' + '{iconMarkup}', iconTpl: '', _textAlignClasses: { left: Ext.baseCSSPrefix + 'title-align-left', center: Ext.baseCSSPrefix + 'title-align-center', right: Ext.baseCSSPrefix + 'title-align-right' }, _iconAlignClasses: { top: Ext.baseCSSPrefix + 'title-icon-top', right: Ext.baseCSSPrefix + 'title-icon-right', bottom: Ext.baseCSSPrefix + 'title-icon-bottom', left: Ext.baseCSSPrefix + 'title-icon-left' }, _rotationClasses: { 0: Ext.baseCSSPrefix + 'title-rotate-none', 1: Ext.baseCSSPrefix + 'title-rotate-right', 2: Ext.baseCSSPrefix + 'title-rotate-left' }, _rotationAngles: { 1: 90, 2: 270 }, baseCls: Ext.baseCSSPrefix + 'title', _titleSuffix: '-title', _glyphCls: Ext.baseCSSPrefix + 'title-glyph', _iconWrapCls: Ext.baseCSSPrefix + 'title-icon-wrap', _baseIconCls: Ext.baseCSSPrefix + 'title-icon', _itemCls: Ext.baseCSSPrefix + 'title-item', _textCls: Ext.baseCSSPrefix + 'title-text', afterComponentLayout: function() { var me = this, rotation = me.getRotation(), lastBox, lastX, el; if (rotation && !Ext.isIE8) { el = me.el; lastBox = me.lastBox; lastX = lastBox.x; el.setStyle(me._getVerticalAdjustDirection(), (lastX + ((rotation === 1) ? lastBox.width : -lastBox.height)) + 'px'); } this.callParent(); }, onRender: function() { var me = this, rotation = me.getRotation(), el = me.el; me.callParent(); if (rotation) { el.setVertical(me._rotationAngles[rotation]); } if (Ext.supports.FixedTableWidthBug) { el._needsTableWidthFix = true; } }, applyText: function(text) { if (!text) { text = ' '; } return text; }, beforeRender: function() { var me = this; me.callParent(); me.addCls(me._rotationClasses[me.getRotation()]); me.addCls(me._textAlignClasses[me.getTextAlign()]); }, getIconMarkup: function() { return this.getTpl('iconTpl').apply(this.getIconRenderData()); }, getIconRenderData: function() { var me = this, icon = me.getIcon(), iconCls = me.getIconCls(), glyph = me.getGlyph(), glyphFontFamily = Ext._glyphFontFamily, iconAlign = me.getIconAlign(), glyphParts; if (typeof glyph === 'string') { glyphParts = glyph.split('@'); glyph = glyphParts[0]; glyphFontFamily = glyphParts[1]; } return { id: me.id, ui: me.ui, itemCls: me._itemCls, iconUrl: icon, iconCls: iconCls, iconWrapCls: me._iconWrapCls, baseIconCls: me._baseIconCls, iconAlignCls: me._iconAlignClasses[iconAlign], glyph: glyph, glyphCls: glyph ? me._glyphCls : '', glyphFontFamily: glyphFontFamily }; }, initRenderData: function() { var me = this, iconAlign, renderData; renderData = Ext.apply({ text: me.getText(), headerRole: me.headerRole, id: me.id, ui: me.ui, itemCls: me._itemCls, textCls: me._textCls, iconMarkup: null, iconBeforeTitle: null }, me.callParent()); if (me._hasIcon()) { iconAlign = me.getIconAlign(); renderData.iconMarkup = me.getIconMarkup(); renderData.iconBeforeTitle = (iconAlign === 'top' || iconAlign === 'left'); } return renderData; }, onAdded: function(container, pos, instanced) { var me = this, suffix = me._titleSuffix, baseCls = container.baseCls; me.addCls([ baseCls + suffix, baseCls + suffix + '-' + container.ui ]); me.callParent([ container, pos, instanced ]); }, updateGlyph: function(glyph, oldGlyph) { glyph = glyph || 0; var me = this, glyphCls = me._glyphCls, iconEl, fontFamily, glyphParts; me.glyph = glyph; if (me.rendered) { me._syncIconVisibility(); iconEl = me.iconEl; if (typeof glyph === 'string') { glyphParts = glyph.split('@'); glyph = glyphParts[0]; fontFamily = glyphParts[1] || Ext._glyphFontFamily; } if (!glyph) { iconEl.dom.innerHTML = ''; iconEl.removeCls(glyphCls); } else if (oldGlyph !== glyph) { iconEl.dom.innerHTML = '&#' + glyph + ';'; iconEl.addCls(glyphCls); } if (fontFamily) { iconEl.setStyle('font-family', fontFamily); } if (me._didIconStateChange(oldGlyph, glyph)) { me.updateLayout(); } } }, updateIcon: function(icon, oldIcon) { icon = icon || ''; var me = this, iconEl; if (me.rendered && icon !== oldIcon) { me._syncIconVisibility(); iconEl = me.iconEl; iconEl.setStyle('background-image', icon ? 'url(' + icon + ')' : ''); if (me._didIconStateChange(oldIcon, icon)) { me.updateLayout(); } } }, updateIconAlign: function(align, oldAlign) { var me = this, iconWrapEl = me.iconWrapEl, el, iconAlignClasses; if (me.iconWrapEl) { el = me.el; iconAlignClasses = me._iconAlignClasses; if (oldAlign) { iconWrapEl.removeCls(iconAlignClasses[oldAlign]); } iconWrapEl.addCls(iconAlignClasses[align]); if (align === 'top' || align === 'left') { el.insertFirst(iconWrapEl); } else { el.appendChild(iconWrapEl); } me.updateLayout(); } }, updateIconCls: function(cls, oldCls) { cls = cls || ''; var me = this, iconEl; if (me.rendered && oldCls !== cls) { me._syncIconVisibility(); iconEl = me.iconEl; if (oldCls) { iconEl.removeCls(oldCls); } iconEl.addCls(cls); if (me._didIconStateChange(oldCls, cls)) { me.updateLayout(); } } }, updateRotation: function(rotation, oldRotation) { var me = this, el, rotationClasses; if (me.rendered) { el = me.el; rotationClasses = me._rotationClasses; me.removeCls(rotationClasses[oldRotation]); me.addCls(rotationClasses[rotation]); el.setHorizontal(); if (rotation) { el.setVertical(me._rotationAngles[rotation]); } el.setStyle({ right: '', left: '', top: '', height: '', width: '' }); me.lastBox = null; me.updateLayout(); } }, updateText: function(text) { if (this.rendered) { this.textEl.setHtml(text); this.updateLayout(); } }, updateTextAlign: function(align, oldAlign) { var me = this, textAlignClasses = me._textAlignClasses; if (me.rendered) { if (oldAlign) { me.removeCls(textAlignClasses[oldAlign]); } me.addCls(textAlignClasses[align]); me.updateLayout(); } }, privates: { _getVerticalAdjustDirection: function() { return 'left'; }, _didIconStateChange: function(old, current) { var currentEmpty = Ext.isEmpty(current); return Ext.isEmpty(old) ? !currentEmpty : currentEmpty; }, _hasIcon: function() { return !!(this.getIcon() || this.getIconCls() || this.getGlyph()); }, _syncIconVisibility: function() { var me = this, el = me.el, hasIcon = me._hasIcon(), iconWrapEl = me.iconWrapEl, isBefore, iconAlign; if (hasIcon && !iconWrapEl) { iconAlign = me.iconAlign; isBefore = (iconAlign === 'left' || iconAlign === 'top'); el.dom.insertAdjacentHTML(isBefore ? 'afterbegin' : 'beforeend', me.getIconMarkup()); iconWrapEl = me.iconWrapEl = el[isBefore ? 'first' : 'last'](); me.iconEl = iconWrapEl.first(); } if (iconWrapEl) { iconWrapEl.setDisplayed(hasIcon); } } } }); Ext.define('Ext.panel.Tool', { extend: 'Ext.Component', uses: [ 'Ext.tip.QuickTipManager' ], xtype: 'tool', isTool: true, focusable: true, baseCls: Ext.baseCSSPrefix + 'tool', disabledCls: Ext.baseCSSPrefix + 'tool-disabled', toolPressedCls: Ext.baseCSSPrefix + 'tool-pressed', toolOverCls: Ext.baseCSSPrefix + 'tool-over', ariaRole: 'button', childEls: [ 'toolEl' ], renderTpl: [ '' ], toolOwner: null, tooltipType: 'qtip', stopEvent: true, cacheHeight: true, cacheWidth: true, _toolTypes: { close: 1, collapse: 1, down: 1, expand: 1, gear: 1, help: 1, left: 1, maximize: 1, minimize: 1, minus: 1, next: 1, pin: 1, plus: 1, prev: 1, print: 1, refresh: 1, restore: 1, right: 1, save: 1, search: 1, toggle: 1, unpin: 1, up: 1 }, initComponent: function() { var me = this; if (me.id && me._toolTypes[me.id]) { Ext.Error.raise('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; Ext.applyIf(me.renderData, { baseCls: me.baseCls, blank: Ext.BLANK_IMAGE_URL, type: me.type }); me.tooltip = me.tooltip || me.qtip; me.callParent(); }, afterRender: function() { var me = this, tip; me.callParent(arguments); me.el.on({ click: me.onClick, mousedown: me.onMouseDown, mouseover: me.onMouseOver, mouseout: me.onMouseOut, scope: me }); tip = me.tooltip; if (tip) { me.setTooltip(tip); } }, tipAttrs: { qtip: 'data-qtip' }, setTooltip: function(tooltip, type) { var me = this, oldTip = me.tooltip, oldType = me.tooltipType, id = me.id, el = me.el, attr; if (oldTip && Ext.quickTipsActive && Ext.isObject(oldTip)) { Ext.tip.QuickTipManager.unregister(id); } me.tooltip = tooltip; if (type) { me.tooltipType = type; } if (tooltip) { if (Ext.quickTipsActive && Ext.isObject(tooltip)) { Ext.tip.QuickTipManager.register(Ext.apply({ target: id }, tooltip)); } else if (el) { if (type && oldType && type !== oldType) { attr = me.tipAttrs[oldType] || 'title'; el.dom.removeAttribute(attr); } attr = me.tipAttrs[type || oldType] || 'title'; el.dom.setAttribute(attr, tooltip); } } }, setType: function(type) { var me = this, oldType = me.type; me.type = type; if (me.rendered) { if (oldType) { me.toolEl.removeCls(me.baseCls + '-' + oldType); } me.toolEl.addCls(me.baseCls + '-' + type); } else { me.renderData.type = type; } return me; }, onDestroy: function() { var me = this, keyMap = me.keyMap; me.setTooltip(null); if (keyMap) { keyMap.destroy(); me.keyMap = null; } delete me.toolOwner; me.callParent(); }, privates: { getFocusEl: function() { return this.el; }, onClick: function(e, target) { var me = this; if (me.disabled) { return false; } me.el.removeCls(me.toolPressedCls + ' ' + me.toolOverCls); if (me.stopEvent !== false) { e.stopEvent(); } if (me.handler) { Ext.callback(me.handler, me.scope, [ e, target, me.ownerCt, me ], 0, me); } else if (me.callback) { Ext.callback(me.callback, me.scope, [ me.toolOwner || me.ownerCt, me, e ], 0, me); } me.fireEvent('click', me, e, me.toolOwner || me.ownerCt); return true; }, onMouseDown: function() { if (this.disabled) { return false; } this.el.addCls(this.toolPressedCls); }, onMouseOver: function() { if (this.disabled) { return false; } this.el.addCls(this.toolOverCls); }, onMouseOut: function() { this.el.removeCls(this.toolOverCls); } } }); Ext.define('Ext.panel.Header', { extend: 'Ext.panel.Bar', requires: [ 'Ext.panel.Title', 'Ext.panel.Tool' ], xtype: 'header', isHeader: true, defaultType: 'tool', indicateDrag: false, weight: -1, shrinkWrap: 3, iconAlign: 'left', titleAlign: 'left', titlePosition: 0, titleRotation: 'default', beforeRenderConfig: { glyph: null, icon: null, iconCls: null, iconAlign: null, title: { $value: { ariaRole: 'presentation', xtype: 'title', flex: 1 }, merge: function(newValue, oldValue) { if (typeof newValue === 'string') { newValue = { text: newValue }; } return Ext.merge(oldValue ? Ext.Object.chain(oldValue) : {}, newValue); } }, titleAlign: null, titlePosition: null, titleRotation: null }, headerCls: Ext.baseCSSPrefix + 'header', initComponent: function() { var me = this, items = me.items, itemPosition = me.itemPosition, cls = [ me.headerCls ]; me.tools = me.tools || []; me.items = items = (items ? items.slice() : []); if (itemPosition !== undefined) { me._userItems = items.slice(); me.items = items = []; } me.indicateDragCls = me.headerCls + '-draggable'; if (me.indicateDrag) { cls.push(me.indicateDragCls); } me.addCls(cls); me.syncNoBorderCls(); Ext.Array.push(items, me.tools); me.tools.length = 0; me.callParent(); me.on({ dblclick: me.onDblClick, click: me.onClick, element: 'el', scope: me }); }, addTool: function(tool) { this.add(Ext.ComponentManager.create(tool, 'tool')); }, afterLayout: function() { var me = this, frameBR, frameTR, frameTL, xPos; if (me.vertical) { frameTR = me.frameTR; if (frameTR) { frameBR = me.frameBR; frameTL = me.frameTL; xPos = (me.getWidth() - frameTR.getPadding('r') - ((frameTL) ? frameTL.getPadding('l') : me.el.getBorderWidth('l'))) + 'px'; frameBR.setStyle('background-position-x', xPos); frameTR.setStyle('background-position-x', xPos); } } this.callParent(); }, applyTitle: function(title, oldTitle) { var me = this, isString, configHasRotation; title = title || ''; isString = typeof title === 'string'; if (isString) { title = { text: title }; } if (oldTitle) { Ext.suspendLayouts(); oldTitle.setConfig(title); Ext.resumeLayouts(true); title = oldTitle; } else { if (isString) { title.xtype = 'title'; } title.ui = me.ui; title.headerRole = me.headerRole; configHasRotation = ('rotation' in title); title = Ext.create(title); if (!configHasRotation && me.vertical && me.titleRotation === 'default') { title.rotation = 1; } } return title; }, applyTitlePosition: function(position) { var max = this.items.getCount(); if (this._titleInItems) { --max; } return Math.max(Math.min(position, max), 0); }, beforeLayout: function() { this.callParent(); this.syncBeforeAfterTitleClasses(); }, beforeRender: function() { var me = this, itemPosition = me.itemPosition; me.protoEl.unselectable(); me.callParent(); if (itemPosition !== undefined) { me.insert(itemPosition, me._userItems); } }, getTools: function() { return this.tools.slice(); }, onAdd: function(component, index) { var tools = this.tools; this.callParent([ component, index ]); if (component.isTool) { tools.push(component); tools[component.type] = component; } }, onAdded: function(container, pos, instanced) { this.syncNoBorderCls(); this.callParent([ container, pos, instanced ]); }, onRemoved: function(container, pos, instanced) { this.syncNoBorderCls(); this.callParent([ container, pos, instanced ]); }, setDock: function(dock) { var me = this, title = me.getTitle(), rotation = me.getTitleRotation(), titleRotation = title.getRotation(); Ext.suspendLayouts(); me.callParent([ dock ]); if (rotation === 'default') { rotation = (me.vertical ? 1 : 0); if (rotation !== titleRotation) { title.setRotation(rotation); } if (me.rendered) { me.resetItemMargins(); } } Ext.resumeLayouts(true); }, updateGlyph: function(glyph) { this.getTitle().setGlyph(glyph); }, updateIcon: function(icon) { this.getTitle().setIcon(icon); }, updateIconAlign: function(align, oldAlign) { this.getTitle().setIconAlign(align); }, updateIconCls: function(cls) { this.getTitle().setIconCls(cls); }, updateTitle: function(title, oldTitle) { if (!oldTitle) { this.insert(this.getTitlePosition(), title); this._titleInItems = true; } this.titleCmp = title; }, updateTitleAlign: function(align, oldAlign) { this.getTitle().setTextAlign(align); }, updateTitlePosition: function(position) { this.insert(position, this.getTitle()); }, updateTitleRotation: function(rotation) { if (rotation === 'default') { rotation = (this.vertical ? 1 : 0); } this.getTitle().setRotation(rotation); }, privates: { fireClickEvent: function(type, e) { var toolCls = '.' + Ext.panel.Tool.prototype.baseCls; if (!e.getTarget(toolCls)) { this.fireEvent(type, this, e); } }, getFocusEl: function() { return this.el; }, getFramingInfoCls: function() { var me = this, cls = me.callParent(), owner = me.ownerCt; if (!me.expanding && owner && (owner.collapsed || me.isCollapsedExpander)) { cls += '-' + owner.collapsedCls; } return cls + '-' + me.dock; }, onClick: function(e) { this.fireClickEvent('click', e); }, onDblClick: function(e) { this.fireClickEvent('dblclick', e); }, syncBeforeAfterTitleClasses: function(force) { var me = this, items = me.items, childItems = items.items, titlePosition = me.getTitlePosition(), itemCount = childItems.length, itemGeneration = items.generation, syncGen = me.syncBeforeAfterGen, afterCls, beforeCls, i, item; if (!force && (syncGen === itemGeneration)) { return; } me.syncBeforeAfterGen = itemGeneration; for (i = 0; i < itemCount; ++i) { item = childItems[i]; afterCls = item.afterTitleCls || (item.afterTitleCls = item.baseCls + '-after-title'); beforeCls = item.beforeTitleCls || (item.beforeTitleCls = item.baseCls + '-before-title'); if (!me.title || i < titlePosition) { if (syncGen) { item.removeCls(afterCls); } item.addCls(beforeCls); } else if (i > titlePosition) { if (syncGen) { item.removeCls(beforeCls); } item.addCls(afterCls); } } }, syncNoBorderCls: function() { var me = this, ownerCt = this.ownerCt, noBorderCls = me.headerCls + '-noborder'; if (ownerCt ? (ownerCt.border === false && !ownerCt.frame) : me.border === false) { me.addCls(noBorderCls); } else { me.removeCls(noBorderCls); } } } }); Ext.define('Ext.layout.container.boxOverflow.None', { alternateClassName: 'Ext.layout.boxOverflow.None', alias: [ 'box.overflow.none', 'box.overflow.None' ], mixins: [ 'Ext.mixin.Factoryable' ], factoryConfig: { defaultType: 'none' }, isBoxOverflowHandler: true, $configPrefixed: false, $configStrict: false, constructor: function(config) { this.initConfig(config); }, handleOverflow: Ext.emptyFn, clearOverflow: Ext.emptyFn, beginLayout: Ext.emptyFn, beginLayoutCycle: Ext.emptyFn, calculate: function(ownerContext) { var me = this, plan = ownerContext.state.boxPlan, overflow; if (plan && plan.tooNarrow) { overflow = me.handleOverflow(ownerContext); if (overflow) { if (overflow.reservedSpace) { me.layout.publishInnerCtSize(ownerContext, overflow.reservedSpace); } } } else { me.clearOverflow(); } }, completeLayout: Ext.emptyFn, finishedLayout: function(ownerContext) { var me = this, owner = me.layout.owner, hiddens, hiddenCount; if (owner.hasListeners.overflowchange) { hiddens = owner.query('>[hidden]'); hiddenCount = hiddens.length; if (hiddenCount !== me.lastHiddenCount) { owner.fireEvent('overflowchange', me.lastHiddenCount, hiddenCount, hiddens); me.lastHiddenCount = hiddenCount; } } }, onRemove: Ext.emptyFn, getItem: function(item) { return this.layout.owner.getComponent(item); }, getOwnerType: function(owner) { var type; if (owner.isToolbar) { type = 'toolbar'; } else if (owner.isTabBar) { type = 'tab-bar'; } else if (owner.isMenu) { type = 'menu'; } else if (owner.isBreadcrumb) { type = 'breadcrumb'; } else { type = owner.getXType(); } return type; }, getPrefixConfig: Ext.emptyFn, getSuffixConfig: Ext.emptyFn, getOverflowCls: function() { return ''; }, setVertical: function() { var me = this, layout = me.layout, innerCt = layout.innerCt; innerCt.removeCls(me.getOverflowCls(layout.oppositeDirection)); innerCt.addCls(me.getOverflowCls(layout.direction)); } }); Ext.define('Ext.util.ClickRepeater', { extend: 'Ext.util.Observable', constructor: function(el, config) { var me = this; me.el = Ext.get(el); me.el.unselectable(); Ext.apply(me, config); me.callParent(); if (!me.disabled) { me.disabled = true; me.enable(); } if (me.handler) { me.on("click", me.handler, me.scope || me); } }, interval: 20, delay: 250, preventDefault: true, stopDefault: false, timer: 0, enable: function() { if (this.disabled) { this.el.on('mousedown', this.handleMouseDown, this); if (Ext.isIE8) { 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.clearListeners(); } 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); this.clearListeners(); }, handleDblClick: function(e) { clearTimeout(this.timer); this.fireEvent("mousedown", this, e); this.fireEvent("click", this, e); }, handleMouseDown: function(e) { clearTimeout(this.timer); 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; } 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(e) { this.el.un("mouseover", this.handleMouseReturn, this); if (this.pressedCls) { this.el.addCls(this.pressedCls); } this.click(e); }, 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.container.boxOverflow.Scroller', { extend: 'Ext.layout.container.boxOverflow.None', requires: [ 'Ext.util.ClickRepeater', 'Ext.Element' ], alternateClassName: 'Ext.layout.boxOverflow.Scroller', alias: [ 'box.overflow.scroller', 'box.overflow.Scroller' ], mixins: { observable: 'Ext.mixin.Observable' }, animateScroll: false, scrollIncrement: 20, wheelIncrement: 10, scrollRepeatInterval: 60, scrollDuration: 400, scrollerCls: Ext.baseCSSPrefix + 'box-scroller', beforeSuffix: '-before-scroller', afterSuffix: '-after-scroller', constructor: function(config) { var me = this; me.mixins.observable.constructor.call(me, config); me.scrollPosition = 0; me.scrollSize = 0; }, getPrefixConfig: function() { return { role: 'presentation', id: this.layout.owner.id + this.beforeSuffix, cls: this.createScrollerCls('beforeX'), style: 'display:none' }; }, getSuffixConfig: function() { return { role: 'presentation', id: this.layout.owner.id + this.afterSuffix, cls: this.createScrollerCls('afterX'), style: 'display:none' }; }, createScrollerCls: function(xName) { var me = this, layout = me.layout, owner = layout.owner, type = me.getOwnerType(owner), scrollerCls = me.scrollerCls, cls = scrollerCls + ' ' + scrollerCls + '-' + layout.names[xName] + ' ' + scrollerCls + '-' + type + ' ' + scrollerCls + '-' + type + '-' + owner.ui; if (owner.plain) { cls += ' ' + scrollerCls + '-plain'; } return cls; }, getOverflowCls: function(direction) { return this.scrollerCls + '-body-' + direction; }, beginLayout: function(ownerContext) { ownerContext.innerCtScrollPos = this.getScrollPosition(); this.callParent(arguments); }, finishedLayout: function(ownerContext) { var me = this, plan = ownerContext.state.boxPlan, layout = me.layout, names = layout.names, scrollPos = Math.min(me.getMaxScrollPosition(), ownerContext.innerCtScrollPos), lastProps; if (plan && plan.tooNarrow) { lastProps = ownerContext.childItems[ownerContext.childItems.length - 1].props; me.scrollSize = lastProps[names.x] + lastProps[names.width]; me.updateScrollButtons(); } layout.innerCt[names.setScrollLeft](scrollPos); this.callParent([ ownerContext ]); }, handleOverflow: function(ownerContext) { var me = this, names = me.layout.names, getWidth = names.getWidth, parallelMargins = names.parallelMargins, scrollerWidth, targetPaddingWidth, beforeScroller, afterScroller; me.showScrollers(); beforeScroller = me.getBeforeScroller(); afterScroller = me.getAfterScroller(); scrollerWidth = beforeScroller[getWidth]() + afterScroller[getWidth]() + beforeScroller.getMargin(parallelMargins) + afterScroller.getMargin(parallelMargins); targetPaddingWidth = ownerContext.targetContext.getPaddingInfo()[names.width]; return { reservedSpace: Math.max(scrollerWidth - targetPaddingWidth, 0) }; }, getBeforeScroller: function() { var me = this; return me._beforeScroller || (me._beforeScroller = me.createScroller(me.beforeSuffix, 'beforeRepeater', 'scrollLeft')); }, getAfterScroller: function() { var me = this; return me._afterScroller || (me._afterScroller = me.createScroller(me.afterSuffix, 'afterRepeater', 'scrollRight')); }, createScroller: function(suffix, repeaterName, scrollHandler) { var me = this, owner = me.layout.owner, scrollerCls = me.scrollerCls, scrollerEl; scrollerEl = owner.el.getById(owner.id + suffix); scrollerEl.addClsOnOver(scrollerCls + '-hover'); scrollerEl.addClsOnClick(scrollerCls + '-pressed'); scrollerEl.setVisibilityMode(Ext.Element.DISPLAY); me[repeaterName] = new Ext.util.ClickRepeater(scrollerEl, { interval: me.scrollRepeatInterval, handler: scrollHandler, scope: me }); return scrollerEl; }, createWheelListener: function() { var me = this; me.wheelListener = me.layout.innerCt.on('mousewheel', me.onMouseWheel, me, { destroyable: true }); }, onMouseWheel: function(e) { e.stopEvent(); this.scrollBy(this.getWheelDelta(e) * this.wheelIncrement * -1, false); }, getWheelDelta: function(e) { return e.getWheelDelta(); }, clearOverflow: function() { this.hideScrollers(); }, showScrollers: function() { var me = this; if (!me.wheelListener) { me.createWheelListener(); } me.getBeforeScroller().show(); me.getAfterScroller().show(); me.layout.owner.addClsWithUI(me.layout.direction === 'vertical' ? 'vertical-scroller' : 'scroller'); }, hideScrollers: function() { var me = this, beforeScroller = me.getBeforeScroller(), afterScroller = me.getAfterScroller(); if (beforeScroller) { beforeScroller.hide(); afterScroller.hide(); me.layout.owner.removeClsWithUI(me.layout.direction === 'vertical' ? 'vertical-scroller' : 'scroller'); } }, destroy: function() { Ext.destroyMembers(this, 'beforeRepeater', 'afterRepeater', '_beforeScroller', '_afterScroller', 'wheelListener'); }, scrollBy: function(delta, animate) { this.scrollTo(this.getScrollPosition() + delta, animate); }, getScrollAnim: function() { return { duration: this.scrollDuration, callback: this.updateScrollButtons, scope: this }; }, updateScrollButtons: function() { var me = this, beforeScroller = me.getBeforeScroller(), afterScroller = me.getAfterScroller(), disabledCls; if (!beforeScroller || !afterScroller) { return; } disabledCls = me.scrollerCls + '-disabled'; beforeScroller[me.atExtremeBefore() ? 'addCls' : 'removeCls'](disabledCls); afterScroller[me.atExtremeAfter() ? 'addCls' : 'removeCls'](disabledCls); me.scrolling = false; }, scrollLeft: function() { this.scrollBy(-this.scrollIncrement, false); }, scrollRight: function() { this.scrollBy(this.scrollIncrement, false); }, getScrollPosition: function() { var me = this, layout = me.layout, result; if (isNaN(me.scrollPosition)) { result = layout.innerCt[layout.names.getScrollLeft](); } else { result = me.scrollPosition; } return result; }, getMaxScrollPosition: function() { var me = this, layout = me.layout, maxScrollPos = me.scrollSize - layout.innerCt[layout.names.getWidth](); return (maxScrollPos < 0) ? 0 : maxScrollPos; }, atExtremeBefore: function() { return !this.getScrollPosition(); }, atExtremeAfter: function() { return this.getScrollPosition() >= this.getMaxScrollPosition(); }, setVertical: function() { var me = this, beforeScroller = me.getBeforeScroller(), afterScroller = me.getAfterScroller(), names = me.layout.names, scrollerCls = me.scrollerCls; beforeScroller.removeCls(scrollerCls + '-' + names.beforeY); afterScroller.removeCls(scrollerCls + '-' + names.afterY); beforeScroller.addCls(scrollerCls + '-' + names.beforeX); afterScroller.addCls(scrollerCls + '-' + names.afterX); this.callParent(); }, scrollTo: function(position, animate) { var me = this, layout = me.layout, names = layout.names, oldPosition = me.getScrollPosition(), newPosition = Ext.Number.constrain(position, 0, me.getMaxScrollPosition()); if (newPosition !== oldPosition && !me.scrolling) { me.scrollPosition = NaN; if (animate === undefined) { animate = me.animateScroll; } layout.innerCt[names.scrollTo](names.beforeScrollX, newPosition, animate ? me.getScrollAnim() : false); if (animate) { me.scrolling = true; } else { me.updateScrollButtons(); } me.fireEvent('scroll', me, newPosition, animate ? me.getScrollAnim() : false); } }, scrollToItem: function(item, animate) { var me = this, layout = me.layout, owner = layout.owner, names = layout.names, innerCt = layout.innerCt, visibility, box, newPos; item = me.getItem(item); if (item !== undefined) { if (item === owner.items.first()) { newPos = 0; } else if (item === owner.items.last()) { newPos = me.getMaxScrollPosition(); } else { visibility = me.getItemVisibility(item); if (!visibility.fullyVisible) { box = item.getBox(false, true); newPos = box[names.x]; if (visibility.hiddenEnd) { newPos -= (innerCt[names.getWidth]() - box[names.width]); } } } if (newPos !== undefined) { me.scrollTo(newPos, animate); } } }, getItemVisibility: function(item) { var me = this, box = me.getItem(item).getBox(true, true), layout = me.layout, names = layout.names, itemStart = box[names.x], itemEnd = itemStart + box[names.width], scrollStart = me.getScrollPosition(), scrollEnd = scrollStart + layout.innerCt[names.getWidth](); return { hiddenStart: itemStart < scrollStart, hiddenEnd: itemEnd > scrollEnd, fullyVisible: itemStart >= scrollStart && itemEnd <= scrollEnd }; } }); 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, notifyOccluded: false, dragCls: Ext.baseCSSPrefix + 'dd-drag-current', _execOnAll: function(sMethod, args) { var ids = this.ids, i, j, oDD, item; for (i in ids) { if (ids.hasOwnProperty(i)) { item = ids[i]; for (j in item) { if (item.hasOwnProperty(j)) { oDD = item[j]; if (!this.isTypeOfDD(oDD)) { continue; } oDD[sMethod].apply(oDD, args); } } } } }, addListeners: function() { var me = this; me.init(); Ext.getDoc().on({ mouseup: me.handleMouseUp, mousemove: { fn: me.handleMouseMove, capture: false }, dragstart: me.preventDrag, drag: me.preventDrag, dragend: me.preventDrag, capture: true, scope: me }); Ext.getWin().on({ unload: me._onUnload, resize: me._onResize, scope: me }); }, preventDrag: function(e) { if (this.isMouseDown) { e.stopPropagation(); } }, _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: 8, 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, clearGroup) { var me = this, ids = me.ids, groups = oDD.groups, g; if (me.clearingAll) { return; } if (me.dragCurrent === oDD) { me.dragCurrent = null; } for (g in groups) { if (groups.hasOwnProperty(g)) { if (clearGroup) { delete ids[g]; } else if (ids[g]) { delete ids[g][oDD.id]; } } } delete me.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 = [], i, j, dd; for (i in p_oDD.groups) { for (j in this.ids[i]) { 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), i, len; for (i = 0 , len = targets.length; i < len; ++i) { if (targets[i].id === oTargetDD.id) { return true; } } return false; }, isTypeOfDD: function(oDD) { return (oDD && oDD.__ygDragDrop); }, isHandle: function(sDDId, sHandleId) { return (this.handleIds[sDDId] && this.handleIds[sDDId][sHandleId]); }, getDDById: function(id, force) { var i, dd; for (i in this.ids) { dd = this.ids[i][id]; if (dd instanceof Ext.dd.DDTarget || force) { return dd; } } return null; }, handleMouseDown: function(e, oDD) { var me = this, xy, el; me.isMouseDown = true; if (Ext.quickTipsActive) { Ext.tip.QuickTipManager.ddDisable(); } me.currentPoint = e.getPoint(); if (me.dragCurrent) { me.handleMouseUp(e); } me.mousedownEvent = e; me.currentTarget = e.getTarget(); me.dragCurrent = oDD; el = oDD.getEl(); Ext.fly(el).setCapture(); xy = e.getXY(); me.startX = xy[0]; me.startY = xy[1]; me.offsetX = me.offsetY = 0; me.deltaX = me.startX - el.offsetLeft; me.deltaY = me.startY - el.offsetTop; me.dragThreshMet = false; }, startDrag: function(x, y) { var me = this, current = me.dragCurrent, dragEl; clearTimeout(me.clickTimeout); if (current) { current.b4StartDrag(x, y); current.startDrag(x, y); dragEl = current.getDragEl(); if (dragEl) { Ext.fly(dragEl).addCls(me.dragCls); } } me.dragThreshMet = true; }, handleMouseUp: function(e) { var me = this; me.isMouseDown = false; if (Ext.quickTipsActive) { Ext.tip.QuickTipManager.ddEnable(); } if (!me.dragCurrent) { return; } if (Ext.isIE && document.releaseCapture) { document.releaseCapture(); } clearTimeout(me.clickTimeout); if (me.dragThreshMet) { me.fireEvents(e, true); } me.stopDrag(e); me.stopEvent(e); }, stopEvent: function(e) { if (this.stopPropagation) { e.stopPropagation(); } if (this.preventDefault) { e.preventDefault(); } }, stopDrag: function(e) { var me = this, current = me.dragCurrent, dragEl; if (current) { if (me.dragThreshMet) { dragEl = current.getDragEl(); if (dragEl) { Ext.fly(dragEl).removeCls(me.dragCls); } current.b4EndDrag(e); current.endDrag(e); } me.dragCurrent.onMouseUp(e); } me.dragCurrent = null; me.dragOvers = {}; }, handleMouseMove: function(e) { var me = this, current = me.dragCurrent, point = me.currentPoint = e.getPoint(), currentX = point.x, currentY = point.y, diffX, diffY; me.offsetX = currentX - me.startX; me.offsetY = currentY - me.startY; if (!current) { return true; } if (!me.dragThreshMet) { diffX = Math.abs(me.offsetX); diffY = Math.abs(me.offsetY); if (diffX > me.clickPixelThresh || diffY > me.clickPixelThresh) { me.startDrag(me.startX, me.startY); } } if (me.dragThreshMet) { current.b4Drag(e); current.onDrag(e); if (!current.moveOnly) { me.fireEvents(e, false); } } me.stopEvent(e); return true; }, fireEvents: function(e, isDrop) { var me = this, isTouch = Ext.supports.Touch, dragCurrent = me.dragCurrent, mousePoint = me.currentPoint, currentX = mousePoint.x, currentY = mousePoint.y, allTargets = [], oldOvers = [], outEvts = [], overEvts = [], dropEvts = [], enterEvts = [], zoom = isTouch ? document.documentElement.clientWidth / window.innerWidth : 1, dragEl, overTarget, overTargetEl, needsSort, i, len, sGroup, overDragEl; if (!dragCurrent || dragCurrent.isLocked()) { return; } overDragEl = !(dragCurrent.deltaX < 0 || dragCurrent.deltaY < 0); if (isTouch || (!me.notifyOccluded && (!Ext.supports.CSSPointerEvents || Ext.isIE10m || Ext.isOpera) && overDragEl)) { dragEl = dragCurrent.getDragEl(); if (overDragEl) { dragEl.style.visibility = 'hidden'; } e.target = document.elementFromPoint(currentX / zoom, currentY / zoom); if (overDragEl) { dragEl.style.visibility = 'visible'; } } for (i in me.dragOvers) { overTarget = me.dragOvers[i]; delete me.dragOvers[i]; if (!me.isTypeOfDD(overTarget) || overTarget.isDestroyed) { continue; } if (me.notifyOccluded) { if (!this.isOverTarget(mousePoint, overTarget, me.mode)) { outEvts.push(overTarget); } } else { if (!e.within(overTarget.getEl())) { outEvts.push(overTarget); } } oldOvers[i] = true; } for (sGroup in dragCurrent.groups) { if ("string" !== typeof sGroup) { continue; } for (i in me.ids[sGroup]) { overTarget = me.ids[sGroup][i]; if (me.isTypeOfDD(overTarget) && (overTargetEl = overTarget.getEl()) && (overTarget.isTarget) && (!overTarget.isLocked()) && (Ext.fly(overTargetEl).isVisible(true)) && ((overTarget !== dragCurrent) || (dragCurrent.ignoreSelf === false))) { if (me.notifyOccluded) { if ((overTarget.zIndex = me.getZIndex(overTargetEl)) !== -1) { needsSort = true; } allTargets.push(overTarget); } else { if (e.within(overTarget.getEl())) { allTargets.push(overTarget); break; } } } } } if (needsSort) { Ext.Array.sort(allTargets, me.byZIndex); } for (i = 0 , len = allTargets.length; i < len; i++) { overTarget = allTargets[i]; if (me.isOverTarget(mousePoint, overTarget, me.mode)) { if (isDrop) { dropEvts.push(overTarget); } else { if (!oldOvers[overTarget.id]) { enterEvts.push(overTarget); } else { overEvts.push(overTarget); } me.dragOvers[overTarget.id] = overTarget; } if (!me.notifyOccluded) { break; } } } if (me.mode) { if (outEvts.length) { dragCurrent.b4DragOut(e, outEvts); dragCurrent.onDragOut(e, outEvts); } if (enterEvts.length) { dragCurrent.onDragEnter(e, enterEvts); } if (overEvts.length) { dragCurrent.b4DragOver(e, overEvts); dragCurrent.onDragOver(e, overEvts); } if (dropEvts.length) { dragCurrent.b4DragDrop(e, dropEvts); dragCurrent.onDragDrop(e, dropEvts); } } else { for (i = 0 , len = outEvts.length; i < len; ++i) { dragCurrent.b4DragOut(e, outEvts[i].id); dragCurrent.onDragOut(e, outEvts[i].id); } for (i = 0 , len = enterEvts.length; i < len; ++i) { dragCurrent.onDragEnter(e, enterEvts[i].id); } for (i = 0 , len = overEvts.length; i < len; ++i) { dragCurrent.b4DragOver(e, overEvts[i].id); dragCurrent.onDragOver(e, overEvts[i].id); } for (i = 0 , len = dropEvts.length; i < len; ++i) { dragCurrent.b4DragDrop(e, dropEvts[i].id); dragCurrent.onDragDrop(e, dropEvts[i].id); } } if (isDrop && !dropEvts.length) { dragCurrent.onInvalidDrop(e); } }, getZIndex: function(element) { var body = document.body, z, zIndex = -1; element = Ext.getDom(element); while (element !== body) { if (!isNaN(z = Number(Ext.fly(element).getStyle('zIndex')))) { zIndex = z; } element = element.parentNode; } return zIndex; }, byZIndex: function(d1, d2) { return d1.zIndex < d2.zIndex; }, getBestMatch: function(dds) { var winner = null, len = dds.length, i, dd; if (len === 1) { winner = dds[0]; } else { for (i = 0; i < len; ++i) { dd = dds[i]; if (dd.cursorIsOver) { winner = dd; break; } else { if (!winner || winner.overlap.getArea() < dd.overlap.getArea()) { winner = dd; } } } } return winner; }, refreshCache: function(groups) { var sGroup, i, oDD, loc; for (sGroup in groups) { if ("string" !== typeof sGroup) { continue; } for (i in this.ids[sGroup]) { oDD = this.ids[sGroup][i]; if (this.isTypeOfDD(oDD)) { loc = this.getLocation(oDD); if (loc) { this.locationCache[oDD.id] = loc; } else { delete this.locationCache[oDD.id]; } } } } }, 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; } if (oDD.getRegion) { return oDD.getRegion(); } var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l; try { pos = Ext.fly(el).getXY(); } catch (e) {} if (!pos) { return null; } x1 = pos[0]; x2 = x1 + el.offsetWidth; y1 = pos[1]; y2 = y1 + el.offsetHeight; t = y1 - oDD.padding[0]; r = x2 + oDD.padding[1]; b = y2 + oDD.padding[2]; l = x1 - oDD.padding[3]; return new Ext.util.Region(t, r, b, l); }, isOverTarget: function(pt, oTarget, intersect) { var loc = this.locationCache[oTarget.id], dc, pos, el, curRegion, overlap; if (!loc || !this.useCache) { loc = this.getLocation(oTarget); this.locationCache[oTarget.id] = loc; } if (!loc) { return false; } oTarget.cursorIsOver = loc.contains(pt); dc = this.dragCurrent; if (!dc || !dc.getTargetCoord || (!intersect && !dc.constrainX && !dc.constrainY)) { return oTarget.cursorIsOver; } oTarget.overlap = null; pos = dc.getTargetCoord(pt.x, pt.y); el = dc.getDragEl(); curRegion = new Ext.util.Region(pos.y, pos.x + el.offsetWidth, pos.y + el.offsetHeight, pos.x); overlap = curRegion.intersect(loc); if (overlap) { oTarget.overlap = overlap; return (intersect) ? true : oTarget.cursorIsOver; } else { return false; } }, _onUnload: function(e, me) { Ext.dd.DragDropManager.unregAll(); }, unregAll: function() { var me = this, cache = me.elementCache, i; if (me.dragCurrent) { me.stopDrag(); me.dragCurrent = null; } me.clearingAll = true; me._execOnAll("unreg", []); delete me.clearingAll; for (i in cache) { delete cache[i]; } me.elementCache = {}; me.ids = {}; me.handleIds = {}; }, elementCache: {}, getElWrapper: function(id) { var oWrapper = this.elementCache[id]; if (!oWrapper || !oWrapper.el) { oWrapper = this.elementCache[id] = new this.ElementWrapper(Ext.getDom(id)); } return oWrapper; }, getElement: function(id) { return Ext.getDom(id); }, getCss: function(id) { var el = Ext.getDom(id); return (el) ? el.style : null; }, ElementWrapper: function(el) { this.el = el || null; this.id = this.el && el.id; this.css = this.el && el.style; }, getPosX: function(el) { return Ext.fly(el).getX(); }, getPosY: function(el) { return Ext.fly(el).getY(); }, swapNode: function(n1, n2) { if (n1.swapNode) { n1.swapNode(n2); } else { var p = n2.parentNode, s = n2.nextSibling; 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); } } }, getScroll: function() { var doc = window.document, docEl = doc.documentElement, body = doc.body, top = 0, left = 0; if (docEl && (docEl.scrollTop || docEl.scrollLeft)) { top = docEl.scrollTop; left = docEl.scrollLeft; } else if (body) { top = body.scrollTop; left = body.scrollLeft; } return { top: top, left: left }; }, getStyle: function(el, styleProp) { return Ext.fly(el).getStyle(styleProp); }, getScrollTop: function() { return this.getScroll().top; }, getScrollLeft: function() { return this.getScroll().left; }, moveToEl: function(moveEl, targetEl) { var aCoord = Ext.fly(targetEl).getXY(); Ext.fly(moveEl).setXY(aCoord); }, numericSort: function(a, b) { return (a - b); }, 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(DragDropManager) { Ext.onInternalReady(function() { DragDropManager.addListeners(); }); }); Ext.define('Ext.resizer.Splitter', { extend: 'Ext.Component', requires: [ 'Ext.XTemplate' ], uses: [ 'Ext.resizer.SplitterTracker' ], xtype: 'splitter', childEls: [ 'collapseEl' ], renderTpl: [ '', '', '' ], isSplitter: true, baseCls: Ext.baseCSSPrefix + 'splitter', collapsedClsInternal: Ext.baseCSSPrefix + 'splitter-collapsed', canResize: true, collapsible: null, collapseOnDblClick: true, defaultSplitMin: 40, defaultSplitMax: 1000, collapseTarget: 'next', horizontal: false, vertical: false, size: 5, tracker: null, ariaRole: 'separator', focusable: true, tabIndex: 0, getTrackerConfig: function() { return Ext.apply({ xclass: 'Ext.resizer.SplitterTracker', el: this.el, splitter: this }, this.tracker); }, beforeRender: function() { var me = this, target = me.getCollapseTarget(), collapsible = me.collapsible; me.callParent(); if (target.collapsed) { me.addCls(me.collapsedClsInternal); } if (!me.canResize) { me.addCls(me.baseCls + '-noresize'); } Ext.applyIf(me.renderData, { collapseDir: me.getCollapseDirection(), collapsible: (collapsible !== null) ? collapsible : target.collapsible }); me.protoEl.unselectable(); }, onRender: function() { var me = this, collapseEl; me.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); } } me.getCollapseTarget().on({ collapse: me.onTargetCollapse, expand: me.onTargetExpand, beforeexpand: me.onBeforeTargetExpand, beforecollapse: me.onBeforeTargetCollapse, scope: me }); if (me.canResize) { me.tracker = Ext.create(me.getTrackerConfig()); me.relayEvents(me.tracker, [ 'beforedragstart', 'dragstart', 'dragend' ]); } collapseEl = me.collapseEl; if (collapseEl) { collapseEl.lastCollapseDirCls = me.collapseDirProps[me.collapseDirection].cls; } }, getCollapseDirection: function() { var me = this, dir = me.collapseDirection, collapseTarget, idx, items, type; if (!dir) { collapseTarget = me.collapseTarget; if (collapseTarget.isComponent) { dir = collapseTarget.collapseDirection; } if (!dir) { type = me.ownerCt.layout.type; if (collapseTarget.isComponent) { items = me.ownerCt.items; idx = Number(items.indexOf(collapseTarget) === items.indexOf(me) - 1) << 1 | Number(type === 'hbox'); } else { idx = Number(me.collapseTarget === 'prev') << 1 | Number(type === 'hbox'); } dir = [ 'bottom', 'right', 'top', 'left' ][idx]; } me.collapseDirection = dir; } me.setOrientation((dir === 'top' || dir === 'bottom') ? 'horizontal' : 'vertical'); return dir; }, getCollapseTarget: function() { var me = this; return me.collapseTarget.isComponent ? me.collapseTarget : me.collapseTarget === 'prev' ? me.previousSibling() : me.nextSibling(); }, setCollapseEl: function(display) { var el = this.collapseEl; if (el) { el.setDisplayed(display); } }, onBeforeTargetExpand: function(target) { this.setCollapseEl('none'); }, onBeforeTargetCollapse: function() { this.setCollapseEl('none'); }, onTargetCollapse: function(target) { var me = this; if (target === me.getCollapseTarget() && target[me.orientation === 'vertical' ? 'collapsedHorizontal' : 'collapsedVertical']()) { me.el.addCls(me.collapsedClsInternal + ' ' + (me.collapsedCls || '')); } me.setCollapseEl(''); }, onTargetExpand: function(target) { var me = this; me.el.removeCls(me.collapsedClsInternal + ' ' + (me.collapsedCls || '')); me.setCollapseEl(''); }, collapseDirProps: { top: { cls: Ext.baseCSSPrefix + 'layout-split-top' }, right: { cls: Ext.baseCSSPrefix + 'layout-split-right' }, bottom: { cls: Ext.baseCSSPrefix + 'layout-split-bottom' }, left: { cls: Ext.baseCSSPrefix + 'layout-split-left' } }, orientationProps: { horizontal: { opposite: 'vertical', fixedAxis: 'height', stretchedAxis: 'width' }, vertical: { opposite: 'horizontal', fixedAxis: 'width', stretchedAxis: 'height' } }, applyCollapseDirection: function() { var me = this, collapseEl = me.collapseEl, collapseDirProps = me.collapseDirProps[me.collapseDirection], cls; if (collapseEl) { cls = collapseEl.lastCollapseDirCls; if (cls) { collapseEl.removeCls(cls); } collapseEl.addCls(collapseEl.lastCollapseDirCls = collapseDirProps.cls); } }, applyOrientation: function() { var me = this, orientation = me.orientation, orientationProps = me.orientationProps[orientation], defaultSize = me.size, fixedSizeProp = orientationProps.fixedAxis, stretchSizeProp = orientationProps.stretchedAxis, cls = me.baseCls + '-'; me[orientation] = true; me[orientationProps.opposite] = false; if (!me.hasOwnProperty(fixedSizeProp) || me[fixedSizeProp] === '100%') { me[fixedSizeProp] = defaultSize; } if (!me.hasOwnProperty(stretchSizeProp) || me[stretchSizeProp] === defaultSize) { me[stretchSizeProp] = '100%'; } me.removeCls(cls + orientationProps.opposite); me.addCls(cls + orientation); }, setOrientation: function(orientation) { var me = this; if (me.orientation !== orientation) { me.orientation = orientation; me.applyOrientation(); } }, updateOrientation: function() { delete this.collapseDirection; this.getCollapseDirection(); this.applyCollapseDirection(); }, toggleTargetCmp: function(e, t) { var cmp = this.getCollapseTarget(), placeholder = cmp.placeholder, toggle; if (Ext.isFunction(cmp.expand) && Ext.isFunction(cmp.collapse)) { if (placeholder && !placeholder.hidden) { toggle = true; } else { toggle = !cmp.hidden; } if (toggle) { if (cmp.collapsed) { cmp.expand(); } else if (cmp.collapseDirection) { cmp.collapse(); } else { cmp.collapse(this.renderData.collapseDir); } } } }, setSize: function() { var me = this; me.callParent(arguments); if (Ext.isIE && me.el) { me.el.repaint(); } }, beforeDestroy: function() { Ext.destroy(this.tracker); this.callParent(); } }); Ext.define('Ext.layout.container.Box', { extend: 'Ext.layout.container.Container', alias: 'layout.box', alternateClassName: 'Ext.layout.BoxLayout', requires: [ 'Ext.layout.container.boxOverflow.None', 'Ext.layout.container.boxOverflow.Scroller', 'Ext.util.Format', 'Ext.dd.DragDropManager', 'Ext.resizer.Splitter' ], type: 'box', config: { align: 'begin', constrainAlign: false, enableSplitters: true, overflowHandler: { $value: null, merge: function(newValue, oldValue) { if (typeof newValue === 'string') { newValue = { type: newValue }; } return Ext.merge(oldValue ? Ext.Object.chain(oldValue) : {}, newValue); } }, padding: 0, pack: 'start', stretchMaxPartner: undefined, vertical: false, alignRoundingMethod: 'round' }, itemCls: Ext.baseCSSPrefix + 'box-item', targetCls: Ext.baseCSSPrefix + 'box-layout-ct', targetElCls: Ext.baseCSSPrefix + 'box-target', innerCls: Ext.baseCSSPrefix + 'box-inner', manageMargins: true, createsInnerCt: true, childEls: [ 'innerCt', 'targetEl' ], renderTpl: [ '{%var oc,l=values.$comp.layout,oh=l.overflowHandler;' + 'if (oh && oh.getPrefixConfig!==Ext.emptyFn) {' + 'if(oc=oh.getPrefixConfig())dh.generateMarkup(oc, out)' + '}%}' + '' + '{%if (oh && oh.getSuffixConfig!==Ext.emptyFn) {' + 'if(oc=oh.getSuffixConfig())dh.generateMarkup(oc, out)' + '}%}', { disableFormats: true, definitions: 'var dh=Ext.DomHelper;' } ], constructor: function(config) { var me = this, type; me.callParent(arguments); me.setVertical(me.vertical); me.flexSortFn = me.flexSort.bind(me); type = typeof me.padding; if (type === 'string' || type === 'number') { me.padding = Ext.util.Format.parseBox(me.padding); me.padding.height = me.padding.top + me.padding.bottom; me.padding.width = me.padding.left + me.padding.right; } }, _beginRe: /^(?:begin|left|top)$/, _centerRe: /^(?:center|middle)$/, _endRe: /^(?:end|right|bottom)$/, _percentageRe: /^\s*(\d+(?:\.\d*)?)\s*[%]\s*$/, getItemSizePolicy: function(item, ownerSizeModel) { var me = this, policy = me.sizePolicy, align = me.align, flex = item.flex, key = align, names = me.names, heightName = names.height, widthName = names.width, width = item[widthName], height = item[heightName], percentageRe = me._percentageRe, percentageWidth = percentageRe.test(width), isStretch = (align === 'stretch'), isStretchMax = (align === 'stretchmax'), constrain = me.constrainAlign; if (!ownerSizeModel && (isStretch || flex || percentageWidth || (constrain && !isStretchMax))) { ownerSizeModel = me.owner.getSizeModel(); } if (isStretch) { if (!percentageRe.test(height) && ownerSizeModel[heightName].shrinkWrap) { key = 'stretchmax'; } } else if (!isStretchMax) { if (percentageRe.test(height)) { key = 'stretch'; } else if (constrain && !ownerSizeModel[heightName].shrinkWrap) { key = 'stretchmax'; } else { key = ''; } } if (flex || percentageWidth) { if (!ownerSizeModel[widthName].shrinkWrap) { policy = policy.flex; } } return policy[key]; }, flexSort: function(a, b) { var maxWidthName = this.names.maxWidth, minWidthName = this.names.minWidth, infiniteValue = Infinity, aTarget = a.target, bTarget = b.target, aFlex = aTarget.flex, bFlex = bTarget.flex, result = 0, aMin, bMin, aMax, bMax, hasMin, hasMax; aMax = aTarget[maxWidthName] || infiniteValue; bMax = bTarget[maxWidthName] || infiniteValue; aMin = aTarget[minWidthName] || 0; bMin = bTarget[minWidthName] || 0; hasMin = isFinite(aMin) || isFinite(bMin); hasMax = isFinite(aMax) || isFinite(bMax); if (hasMin || hasMax) { if (hasMax) { result = aMax - bMax; } if (result === 0 && hasMin) { result = bMin - aMin; } if (result === 0) { if (hasMax) { result = bFlex - aFlex; } else { result = aFlex - bFlex; } } } return result; }, isItemBoxParent: function(itemContext) { return true; }, isItemShrinkWrap: function(item) { return true; }, roundFlex: function(width) { return Math.floor(width); }, beginCollapse: function(child) { var me = this; if (me.direction === 'vertical' && child.collapsedVertical()) { child.collapseMemento.capture([ 'flex' ]); delete child.flex; } else if (me.direction === 'horizontal' && child.collapsedHorizontal()) { child.collapseMemento.capture([ 'flex' ]); delete child.flex; } }, beginExpand: function(child) { child.collapseMemento.restore([ 'flex' ]); }, beginLayout: function(ownerContext) { var me = this, owner = me.owner, smp = owner.stretchMaxPartner, style = me.innerCt.dom.style, names = me.names, overflowHandler = me.overflowHandler, scrollable = owner.getScrollable(), scrollPos; ownerContext.boxNames = names; if (overflowHandler) { overflowHandler.beginLayout(ownerContext); } if (typeof smp === 'string') { smp = Ext.getCmp(smp) || owner.query(smp)[0]; } ownerContext.stretchMaxPartner = smp && ownerContext.context.getCmp(smp); me.callParent(arguments); ownerContext.innerCtContext = ownerContext.getEl('innerCt', me); ownerContext.targetElContext = ownerContext.getEl('targetEl', me); ownerContext.ownerScrollable = scrollable = owner.getScrollable(); if (scrollable) { ownerContext.scrollRestore = scrollable.getPosition(); } style.width = ''; style.height = ''; }, beginLayoutCycle: function(ownerContext, firstCycle) { var me = this, state = ownerContext.state, scrollable = ownerContext.ownerScrollable, align = me.align, names = ownerContext.boxNames, pack = me.pack, centerRe = me._centerRe, overflowHandler = me.overflowHandler, canScroll = ownerContext.state.canScroll, widthModel, heightModel; if (overflowHandler) { overflowHandler.beginLayoutCycle(ownerContext, firstCycle); } me.callParent(arguments); ownerContext.parallelSizeModel = widthModel = ownerContext[names.widthModel]; ownerContext.perpendicularSizeModel = heightModel = ownerContext[names.heightModel]; ownerContext.boxOptions = { align: align = { stretch: align === 'stretch', stretchmax: align === 'stretchmax', center: centerRe.test(align), bottom: me._endRe.test(align) }, pack: pack = { center: centerRe.test(pack), end: pack === 'end' } }; if (scrollable) { if (!canScroll) { state.canScroll = { parallel: !widthModel.shrinkWrap && scrollable[names.getX](), perpendicular: !heightModel.shrinkWrap && scrollable[names.getY]() }; } if (!state.actualScroll) { state.actualScroll = { parallel: false, perpendicular: false }; } } if (align.stretch && heightModel.shrinkWrap) { align.stretchmax = true; align.stretch = false; } align.nostretch = !(align.stretch || align.stretchmax); if (widthModel.shrinkWrap) { pack.center = pack.end = false; } me.cacheFlexes(ownerContext); me.targetEl.setWidth(20000); }, cacheFlexes: function(ownerContext) { var me = this, names = ownerContext.boxNames, widthModelName = names.widthModel, heightModelName = names.heightModel, nostretch = ownerContext.boxOptions.align.nostretch, totalFlex = 0, childItems = ownerContext.childItems, i = childItems.length, flexedItems = [], minWidth = 0, smallestHeight = 0, smallestWidth = 0, minWidthName = names.minWidth, minHeightName = names.minHeight, percentageRe = me._percentageRe, percentageWidths = 0, percentageHeights = 0, child, childContext, flex, match, heightModel, widthModel, width, height; while (i--) { childContext = childItems[i]; child = childContext.target; widthModel = childContext[widthModelName]; if (widthModel.calculated) { childContext.flex = flex = child.flex; if (flex) { totalFlex += flex; flexedItems.push(childContext); minWidth += child[minWidthName] || 0; } else { match = percentageRe.exec(child[names.width]); childContext.percentageParallel = parseFloat(match[1]) / 100; ++percentageWidths; } } if (widthModel.configured) { width = child[names.width]; } else { width = child[minWidthName] || 0; } smallestWidth += width; heightModel = childContext[heightModelName]; if (nostretch && heightModel.calculated) { match = percentageRe.exec(child[names.height]); childContext.percentagePerpendicular = parseFloat(match[1]) / 100; ++percentageHeights; } if (heightModel.configured) { height = child[names.height]; } else { height = child[minHeightName] || 0; } if (height > smallestHeight) { smallestHeight = height; } } ownerContext.flexedItems = flexedItems; ownerContext.flexedMinWidth = minWidth; ownerContext.smallestWidth = smallestWidth; ownerContext.smallestHeight = smallestHeight; ownerContext.totalFlex = totalFlex; ownerContext.percentageWidths = percentageWidths; ownerContext.percentageHeights = percentageHeights; Ext.Array.sort(flexedItems, me.flexSortFn); }, calculate: function(ownerContext) { var me = this, names = ownerContext.boxNames, state = ownerContext.state, actualScroll = state.actualScroll, needsScroll = state.needsScroll, canScroll = state.canScroll, plan = state.boxPlan || (state.boxPlan = {}), overflowHandler = me.overflowHandler; plan.targetSize = me.getContainerSize(ownerContext); if (canScroll && !needsScroll) { state.needsScroll = needsScroll = { parallel: canScroll.parallel && plan.targetSize[names.width] < ownerContext.smallestWidth, perpendicular: canScroll.perpendicular && plan.targetSize[names.height] < ownerContext.smallestHeight }; } if (!state.parallelDone) { state.parallelDone = me.calculateParallel(ownerContext, names, plan); } if (!state.perpendicularDone) { state.perpendicularDone = me.calculatePerpendicular(ownerContext, names, plan); } if (state.parallelDone && state.perpendicularDone) { if (canScroll && !state.scrollPass) { if (needsScroll.parallel !== actualScroll.parallel || needsScroll.perpendicular !== actualScroll.perpendicular) { ownerContext.invalidate({ state: { scrollPass: true, canScroll: canScroll, needsScroll: actualScroll } }); me.done = false; return; } } me.publishInnerCtSize(ownerContext); if (me.done && ownerContext.boxOptions.align.stretchmax && !state.stretchMaxDone) { me.calculateStretchMax(ownerContext, names, plan); state.stretchMaxDone = true; } if (overflowHandler) { overflowHandler.calculate(ownerContext); } } else { me.done = false; } }, calculateParallel: function(ownerContext, names, plan) { var me = this, widthShrinkWrap = ownerContext.parallelSizeModel.shrinkWrap, widthName = names.width, childItems = ownerContext.childItems, beforeXName = names.beforeX, afterXName = names.afterX, setWidthName = names.setWidth, childItemsLength = childItems.length, flexedItems = ownerContext.flexedItems, flexedItemsLength = flexedItems.length, pack = ownerContext.boxOptions.pack, padding = me.padding, targetSize = plan.targetSize, containerWidth = targetSize[widthName], state = ownerContext.state, needsScroll = state.needsScroll, canScroll = state.canScroll, totalMargin = 0, left = padding[beforeXName], nonFlexWidth = left + padding[afterXName], scrollbarSize = Ext.getScrollbarSize(), scrollbarWidth = scrollbarSize[names.width], scrollbarHeight = scrollbarSize[names.height], i, childMargins, remainingWidth, remainingFlex, childContext, flex, flexedWidth, contentWidth, childWidth, percentageSpace, availableSpace; if (!widthShrinkWrap && !targetSize[names.gotWidth]) { return false; } for (i = 0; i < childItemsLength; ++i) { childContext = childItems[i]; childMargins = childContext.marginInfo || childContext.getMarginInfo(); totalMargin += childMargins[widthName]; if (!childContext[names.widthModel].calculated) { childWidth = childContext.getProp(widthName); nonFlexWidth += childWidth; if (isNaN(nonFlexWidth)) { return false; } } } nonFlexWidth += totalMargin; if (ownerContext.percentageWidths) { percentageSpace = containerWidth - totalMargin; if (isNaN(percentageSpace)) { return false; } for (i = 0; i < childItemsLength; ++i) { childContext = childItems[i]; if (childContext.percentageParallel) { childWidth = Math.ceil(percentageSpace * childContext.percentageParallel); childWidth = childContext.setWidth(childWidth); nonFlexWidth += childWidth; } } } if (widthShrinkWrap) { availableSpace = 0; plan.tooNarrow = false; } else { availableSpace = containerWidth - nonFlexWidth; if (needsScroll && needsScroll.perpendicular) { availableSpace -= scrollbarHeight; } plan.tooNarrow = availableSpace < ownerContext.flexedMinWidth; if (plan.tooNarrow && canScroll && canScroll.parallel) { state.actualScroll.parallel = true; } } contentWidth = nonFlexWidth; remainingWidth = availableSpace; remainingFlex = ownerContext.totalFlex; for (i = 0; i < flexedItemsLength; i++) { childContext = flexedItems[i]; flex = childContext.flex; flexedWidth = me.roundFlex((flex / remainingFlex) * remainingWidth); flexedWidth = childContext[setWidthName](flexedWidth); contentWidth += flexedWidth; remainingWidth = Math.max(0, remainingWidth - flexedWidth); remainingFlex -= flex; } if (pack.center) { left += remainingWidth / 2; if (left < 0) { left = 0; } } else if (pack.end) { left += remainingWidth; } for (i = 0; i < childItemsLength; ++i) { childContext = childItems[i]; childMargins = childContext.marginInfo; left += childMargins[beforeXName]; childContext.setProp(names.x, left); left += childMargins[afterXName] + childContext.props[widthName]; } contentWidth += ownerContext.targetContext.getPaddingInfo()[widthName]; ownerContext.state.contentWidth = contentWidth; if (needsScroll && needsScroll.perpendicular) { if (widthShrinkWrap) { contentWidth += scrollbarWidth; } ownerContext[names.hasOverflowY] = true; ownerContext.target.componentLayout[names.setWidthInDom] = true; ownerContext[names.invalidateScrollY] = Ext.isIE8; } ownerContext[names.setContentWidth](contentWidth); return true; }, calculatePerpendicular: function(ownerContext, names, plan) { var me = this, state = ownerContext.state, needsScroll = state.needsScroll, canScroll = state.canScroll, heightShrinkWrap = ownerContext.perpendicularSizeModel.shrinkWrap, targetSize = plan.targetSize, childItems = ownerContext.childItems, childItemsLength = childItems.length, mmax = Math.max, heightName = names.height, setHeightName = names.setHeight, beforeYName = names.beforeY, topPositionName = names.y, padding = me.padding, top = padding[beforeYName], availHeight = targetSize[heightName] - top - padding[names.afterY], align = ownerContext.boxOptions.align, isStretch = align.stretch, isStretchMax = align.stretchmax, isCenter = align.center, isBottom = align.bottom, constrain = me.constrainAlign, maxHeight = 0, hasPercentageSizes = 0, onBeforeInvalidateChild = me.onBeforeConstrainInvalidateChild, onAfterInvalidateChild = me.onAfterConstrainInvalidateChild, scrollbarHeight = Ext.getScrollbarSize().height, childTop, i, childHeight, childMargins, diff, height, childContext, stretchMaxPartner, stretchMaxChildren, shrinkWrapParallelOverflow, percentagePerpendicular; if (!heightShrinkWrap && !targetSize[names.gotHeight]) { return false; } if (isStretch || ((isCenter || isBottom) && !heightShrinkWrap)) { if (isNaN(availHeight)) { return false; } } if (needsScroll && needsScroll.parallel) { if (heightShrinkWrap) { shrinkWrapParallelOverflow = true; } else { availHeight -= scrollbarHeight; plan.targetSize[heightName] -= scrollbarHeight; } } if (isStretch) { height = availHeight; maxHeight = mmax(height, ownerContext.smallestHeight); } else { for (i = 0; i < childItemsLength; i++) { childContext = childItems[i]; childMargins = (childContext.marginInfo || childContext.getMarginInfo())[heightName]; if (!(percentagePerpendicular = childContext.percentagePerpendicular)) { childHeight = childContext.getProp(heightName); } else { ++hasPercentageSizes; if (heightShrinkWrap) { continue; } else { childHeight = percentagePerpendicular * availHeight - childMargins; childHeight = childContext[names.setHeight](childHeight); } } if (!heightShrinkWrap && constrain && childContext[names.heightModel].shrinkWrap && childHeight > availHeight) { childContext.invalidate({ before: onBeforeInvalidateChild, after: onAfterInvalidateChild, layout: me, childHeight: availHeight, names: names }); ownerContext.state.parallelDone = false; } if (isNaN(maxHeight = mmax(maxHeight, childHeight + childMargins, childContext.target[names.minHeight] || 0))) { return false; } } } if (shrinkWrapParallelOverflow) { maxHeight += scrollbarHeight; ownerContext[names.hasOverflowX] = true; ownerContext.target.componentLayout[names.setHeightInDom] = true; ownerContext[names.invalidateScrollX] = Ext.isIE8; } stretchMaxPartner = ownerContext.stretchMaxPartner; if (stretchMaxPartner) { ownerContext.setProp('maxChildHeight', maxHeight); stretchMaxChildren = stretchMaxPartner.childItems; if (stretchMaxChildren && stretchMaxChildren.length) { maxHeight = mmax(maxHeight, stretchMaxPartner.getProp('maxChildHeight')); if (isNaN(maxHeight)) { return false; } } } ownerContext[names.setContentHeight](maxHeight + me.padding[heightName] + ownerContext.targetContext.getPaddingInfo()[heightName]); if (shrinkWrapParallelOverflow) { maxHeight -= scrollbarHeight; } if (maxHeight > targetSize[heightName] && canScroll && canScroll.perpendicular) { state.actualScroll.perpendicular = true; } plan.maxSize = maxHeight; if (isStretchMax) { height = maxHeight; } else if (isCenter || isBottom || hasPercentageSizes) { if (constrain) { height = heightShrinkWrap ? maxHeight : availHeight; } else { height = heightShrinkWrap ? maxHeight : mmax(availHeight, maxHeight); } height -= ownerContext.innerCtContext.getBorderInfo()[heightName]; } for (i = 0; i < childItemsLength; i++) { childContext = childItems[i]; childMargins = childContext.marginInfo || childContext.getMarginInfo(); childTop = top + childMargins[beforeYName]; if (isStretch) { childContext[setHeightName](height - childMargins[heightName]); } else { percentagePerpendicular = childContext.percentagePerpendicular; if (heightShrinkWrap && percentagePerpendicular) { childMargins = childContext.marginInfo || childContext.getMarginInfo(); childHeight = percentagePerpendicular * height - childMargins[heightName]; childHeight = childContext.setHeight(childHeight); } if (isCenter) { diff = height - childContext.props[heightName]; if (diff > 0) { childTop = top + Math[me.alignRoundingMethod](diff / 2); } } else if (isBottom) { childTop = mmax(0, height - childTop - childContext.props[heightName]); } } childContext.setProp(topPositionName, childTop); } return true; }, onBeforeConstrainInvalidateChild: function(childContext, options) { var heightModelName = options.names.heightModel; if (!childContext[heightModelName].constrainedMin) { childContext[heightModelName] = Ext.layout.SizeModel.calculated; } }, onAfterConstrainInvalidateChild: function(childContext, options) { var names = options.names; childContext.setProp(names.beforeY, 0); if (childContext[names.heightModel].calculated) { childContext[names.setHeight](options.childHeight); } }, calculateStretchMax: function(ownerContext, names, plan) { var me = this, heightName = names.height, widthName = names.width, childItems = ownerContext.childItems, length = childItems.length, height = plan.maxSize, onBeforeStretchMaxInvalidateChild = me.onBeforeStretchMaxInvalidateChild, onAfterStretchMaxInvalidateChild = me.onAfterStretchMaxInvalidateChild, childContext, props, i, childHeight; for (i = 0; i < length; ++i) { childContext = childItems[i]; props = childContext.props; childHeight = height - childContext.getMarginInfo()[heightName]; if (childHeight !== props[heightName] || childContext[names.heightModel].constrained) { childContext.invalidate({ before: onBeforeStretchMaxInvalidateChild, after: onAfterStretchMaxInvalidateChild, layout: me, childWidth: props[widthName], childHeight: childHeight, childX: props.x, childY: props.y, names: names }); } } }, onBeforeStretchMaxInvalidateChild: function(childContext, options) { var heightModelName = options.names.heightModel; if (!childContext[heightModelName].constrainedMax) { childContext[heightModelName] = Ext.layout.SizeModel.calculated; } }, onAfterStretchMaxInvalidateChild: function(childContext, options) { var names = options.names, childHeight = options.childHeight, childWidth = options.childWidth; childContext.setProp('x', options.childX); childContext.setProp('y', options.childY); if (childContext[names.heightModel].calculated) { childContext[names.setHeight](childHeight); } if (childContext[names.widthModel].calculated) { childContext[names.setWidth](childWidth); } }, completeLayout: function(ownerContext) { var me = this, names = ownerContext.boxNames, invalidateScrollX = ownerContext.invalidateScrollX, invalidateScrollY = ownerContext.invalidateScrollY, overflowHandler = me.overflowHandler, scrollRestore = ownerContext.scrollRestore, dom, el, overflowX, overflowY, styles, scroll, scrollable; if (overflowHandler) { overflowHandler.completeLayout(ownerContext); } if (invalidateScrollX || invalidateScrollY) { el = me.getTarget(); dom = el.dom; styles = dom.style; if (invalidateScrollX) { overflowX = el.getStyle('overflowX'); if (overflowX === 'auto') { overflowX = styles.overflowX; styles.overflowX = 'scroll'; } else { invalidateScrollX = false; } } if (invalidateScrollY) { overflowY = el.getStyle('overflowY'); if (overflowY === 'auto') { overflowY = styles.overflowY; styles.overflowY = 'scroll'; } else { invalidateScrollY = false; } } if (invalidateScrollX || invalidateScrollY) { dom.scrollWidth; if (invalidateScrollX) { styles.overflowX = overflowX; } if (invalidateScrollY) { styles.overflowY = overflowY; } } } if (scrollRestore) { ownerContext.ownerScrollable.scrollTo(scrollRestore.x, scrollRestore.y); } }, finishedLayout: function(ownerContext) { var overflowHandler = this.overflowHandler; if (overflowHandler) { overflowHandler.finishedLayout(ownerContext); } this.callParent(arguments); }, getLayoutItems: function() { var items = this.callParent(), n = items.length, lastVisibleItem, hide, i, item, splitAfter, splitBefore, splitter; for (i = 0; i < n; ++i) { if ((item = items[i]).isSplitter) { continue; } splitter = item.splitter; if (item.hidden) { if (splitter) { if (!splitter.hidden) { splitter.hidden = true; if (splitter.el) { splitter.el.hide(); } } } continue; } if (splitter) { splitBefore = splitter.collapseTarget === 'next'; } else { splitBefore = false; } hide = null; if (lastVisibleItem && splitAfter) { if (splitAfter.hidden) { splitAfter.hidden = false; if (splitAfter.el) { splitAfter.el.show(); } } if (splitBefore) { hide = true; } } else if (splitBefore) { hide = !lastVisibleItem; } if (hide !== null && splitter.hidden !== hide) { splitter.hidden = hide; if (splitter.el) { splitter.el.setVisible(!hide); } } splitAfter = !splitBefore && splitter; lastVisibleItem = item; } if (lastVisibleItem && splitAfter && !splitAfter.hidden) { splitAfter.hidden = true; if (splitAfter.el) { splitAfter.el.hide(); } } return items; }, getScrollerEl: function() { return this.innerCt; }, insertSplitter: function(item, index, hidden, splitterCfg) { var splitter = { xtype: 'splitter', id: item.id + '-splitter', hidden: hidden, splitterFor: item, synthetic: true }, at = index + ((splitterCfg.collapseTarget === 'prev') ? 1 : 0); splitter[this.names.height] = '100%'; if (splitterCfg) { Ext.apply(splitter, splitterCfg); } item.splitter = this.owner.add(at, splitter); }, publishInnerCtSize: function(ownerContext, widthOffset) { widthOffset = widthOffset || 0; var me = this, state = ownerContext.state, names = ownerContext.boxNames, heightName = names.height, widthName = names.width, align = ownerContext.boxOptions.align, padding = me.padding, plan = state.boxPlan, targetSize = plan.targetSize, height = plan.maxSize, needsScroll = state.needsScroll, innerCtContext = ownerContext.innerCtContext, innerCtWidth, innerCtHeight; if (ownerContext.parallelSizeModel.shrinkWrap || (plan.tooNarrow && state.canScroll)) { innerCtWidth = state.contentWidth - ownerContext.targetContext.getPaddingInfo()[widthName]; } else { innerCtWidth = targetSize[widthName]; if (needsScroll && needsScroll.perpendicular) { innerCtWidth -= Ext.getScrollbarSize()[widthName]; } } innerCtWidth -= widthOffset; me.owner.tooNarrow = plan.tooNarrow; if (align.stretch) { innerCtHeight = height; } else { innerCtHeight = plan.maxSize + padding[names.beforeY] + padding[names.afterY] + innerCtContext.getBorderInfo()[heightName]; if (!ownerContext.perpendicularSizeModel.shrinkWrap && (align.center || align.bottom)) { innerCtHeight = Math.max(targetSize[heightName], innerCtHeight); } } innerCtContext[names.setWidth](innerCtWidth); innerCtContext[names.setHeight](innerCtHeight); ownerContext.targetElContext.setWidth(ownerContext.innerCtContext.props.width - (me.vertical ? 0 : (widthOffset || 0))); if (isNaN(innerCtWidth + innerCtHeight)) { me.done = false; } }, onAdd: function(item, index) { var me = this, split = me.enableSplitters && item.split && !item.isButton; me.callParent(arguments); if (split) { if (split === true) { split = { collapseTarget: 'next' }; } else if (Ext.isString(split)) { split = { collapseTarget: split === 'before' ? 'next' : 'prev' }; } else { split = Ext.apply({ collapseTarget: split.side === 'before' ? 'next' : 'prev' }, split); } me.insertSplitter(item, index, !!item.hidden, split); } }, onRemove: function(comp, isDestroying) { var me = this, names = me.names, owner = me.owner, splitter = comp.splitter, overflowHandler = me.overflowHandler, el; me.callParent(arguments); if (splitter && owner.contains(splitter)) { owner.doRemove(splitter, true); comp.splitter = null; } if (overflowHandler) { overflowHandler.onRemove(comp); } if (comp.layoutMarginCap === me.id) { delete comp.layoutMarginCap; } if (!owner.destroying && !isDestroying && comp.rendered) { el = comp.getEl(); if (el) { el.setStyle(names.beforeY, ''); el.setStyle(names.beforeX, ''); el.setStyle('margin', ''); } } }, applyOverflowHandler: function(overflowHandler, oldOverflowHandler) { var type; if (typeof overflowHandler === 'string') { overflowHandler = { type: overflowHandler }; } type = overflowHandler.type; if (oldOverflowHandler && oldOverflowHandler.type === overflowHandler.type) { delete overflowHandler.type; oldOverflowHandler.setConfig(overflowHandler); return oldOverflowHandler; } overflowHandler.layout = this; return Ext.Factory.boxOverflow(overflowHandler); }, getRenderTarget: function() { return this.targetEl; }, getElementTarget: function() { return this.innerCt; }, calculateChildBox: Ext.deprecated(), calculateChildBoxes: Ext.deprecated(), updateChildBoxes: Ext.deprecated(), destroy: function() { var me = this; Ext.destroy(me.innerCt, me.overflowHandler); me.flexSortFn = me.innerCt = null; me.callParent(arguments); }, getRenderData: function() { var data = this.callParent(); data.targetElCls = this.targetElCls; return data; }, updateVertical: function(vertical) { var me = this, overflowHandler = me.overflowHandler, owner = me.owner, props = me._props; Ext.apply(me, vertical ? props.vbox : props.hbox); if (overflowHandler && owner && owner.rendered) { overflowHandler.setVertical(vertical); } }, _props: { 'hbox': { direction: 'horizontal', oppositeDirection: 'vertical', horizontal: true, vertical: false, names: { beforeX: 'left', beforeScrollX: 'left', leftCap: 'Left', afterX: 'right', width: 'width', contentWidth: 'contentWidth', minWidth: 'minWidth', maxWidth: 'maxWidth', widthCap: 'Width', widthModel: 'widthModel', widthIndex: 0, x: 'x', getX: 'getX', setX: 'setX', scrollLeft: 'scrollLeft', overflowX: 'overflowX', hasOverflowX: 'hasOverflowX', invalidateScrollX: 'invalidateScrollX', parallelMargins: 'lr', center: 'middle', beforeY: 'top', afterY: 'bottom', height: 'height', contentHeight: 'contentHeight', minHeight: 'minHeight', maxHeight: 'maxHeight', heightCap: 'Height', heightModel: 'heightModel', heightIndex: 1, y: 'y', getY: 'getY', setY: 'setY', overflowY: 'overflowY', hasOverflowY: 'hasOverflowY', invalidateScrollY: 'invalidateScrollY', perpendicularMargins: 'tb', getWidth: 'getWidth', getHeight: 'getHeight', setWidth: 'setWidth', setHeight: 'setHeight', gotWidth: 'gotWidth', gotHeight: 'gotHeight', setContentWidth: 'setContentWidth', setContentHeight: 'setContentHeight', setWidthInDom: 'setWidthInDom', setHeightInDom: 'setHeightInDom', getScrollLeft: 'getScrollLeft', setScrollLeft: 'setScrollLeft', scrollTo: 'scrollTo' }, sizePolicy: { flex: { '': { readsWidth: 0, readsHeight: 1, setsWidth: 1, setsHeight: 0 }, stretch: { readsWidth: 0, readsHeight: 0, setsWidth: 1, setsHeight: 1 }, stretchmax: { readsWidth: 0, readsHeight: 1, setsWidth: 1, setsHeight: 1 } }, '': { readsWidth: 1, readsHeight: 1, setsWidth: 0, setsHeight: 0 }, stretch: { readsWidth: 1, readsHeight: 0, setsWidth: 0, setsHeight: 1 }, stretchmax: { readsWidth: 1, readsHeight: 1, setsWidth: 0, setsHeight: 1 } } }, 'vbox': { direction: 'vertical', oppositeDirection: 'horizontal', horizontal: false, vertical: true, names: { beforeX: 'top', beforeScrollX: 'top', leftCap: 'Top', afterX: 'bottom', width: 'height', contentWidth: 'contentHeight', minWidth: 'minHeight', maxWidth: 'maxHeight', widthCap: 'Height', widthModel: 'heightModel', widthIndex: 1, x: 'y', getX: 'getY', setX: 'setY', scrollLeft: 'scrollTop', overflowX: 'overflowY', hasOverflowX: 'hasOverflowY', invalidateScrollX: 'invalidateScrollY', parallelMargins: 'tb', center: 'center', beforeY: 'left', afterY: 'right', height: 'width', contentHeight: 'contentWidth', minHeight: 'minWidth', maxHeight: 'maxWidth', heightCap: 'Width', heightModel: 'widthModel', heightIndex: 0, y: 'x', getY: 'getX', setY: 'setX', overflowY: 'overflowX', hasOverflowY: 'hasOverflowX', invalidateScrollY: 'invalidateScrollX', perpendicularMargins: 'lr', getWidth: 'getHeight', getHeight: 'getWidth', setWidth: 'setHeight', setHeight: 'setWidth', gotWidth: 'gotHeight', gotHeight: 'gotWidth', setContentWidth: 'setContentHeight', setContentHeight: 'setContentWidth', setWidthInDom: 'setHeightInDom', setHeightInDom: 'setWidthInDom', getScrollLeft: 'getScrollTop', setScrollLeft: 'setScrollTop', scrollTo: 'scrollTo' }, sizePolicy: { flex: { '': { readsWidth: 1, readsHeight: 0, setsWidth: 0, setsHeight: 1 }, stretch: { readsWidth: 0, readsHeight: 0, setsWidth: 1, setsHeight: 1 }, stretchmax: { readsWidth: 1, readsHeight: 0, setsWidth: 1, setsHeight: 1 } }, '': { readsWidth: 1, readsHeight: 1, setsWidth: 0, setsHeight: 0 }, stretch: { readsWidth: 0, readsHeight: 1, setsWidth: 1, setsHeight: 0 }, stretchmax: { readsWidth: 1, readsHeight: 1, setsWidth: 1, setsHeight: 0 } } } } }); Ext.define('Ext.layout.container.HBox', { extend: 'Ext.layout.container.Box', alias: 'layout.hbox', alternateClassName: 'Ext.layout.HBoxLayout', type: 'hbox', vertical: false }); Ext.define('Ext.layout.container.VBox', { extend: 'Ext.layout.container.Box', alias: 'layout.vbox', alternateClassName: 'Ext.layout.VBoxLayout', type: 'vbox', vertical: true }); Ext.define('Ext.util.KeyMap', { alternateClassName: 'Ext.KeyMap', eventName: 'keydown', constructor: function(config) { var me = this; if ((arguments.length !== 1) || (typeof config === 'string') || config.dom || config.tagName || config === document || config.isComponent) { me.legacyConstructor.apply(me, arguments); return; } Ext.apply(me, config); me.bindings = []; if (!me.target.isComponent) { me.target = Ext.get(me.target); } if (me.binding) { me.addBinding(me.binding); } else if (config.key) { me.addBinding(config); } me.enable(); }, legacyConstructor: function(el, binding, eventName) { var me = this; Ext.apply(me, { target: Ext.get(el), eventName: eventName || me.eventName, bindings: [] }); if (binding) { me.addBinding(binding); } me.enable(); }, addBinding: function(binding) { var me = this, keyCode = binding.key, i, len; if (me.processing) { me.bindings = me.bindings.slice(0); } if (Ext.isArray(binding)) { for (i = 0 , len = binding.length; i < len; i++) { me.addBinding(binding[i]); } return; } me.bindings.push(Ext.apply({ keyCode: me.processKeys(keyCode) }, binding)); }, removeBinding: function(binding) { var me = this, bindings = me.bindings, len = bindings.length, i, item, keys; if (me.processing) { me.bindings = bindings.slice(0); } keys = me.processKeys(binding.key); for (i = 0; i < len; ++i) { item = bindings[i]; if ((item.fn || item.handler) === (binding.fn || binding.handler) && item.scope === binding.scope) { if (binding.alt === item.alt && binding.crtl === item.crtl && binding.shift === item.shift) { if (Ext.Array.equals(item.keyCode, keys)) { Ext.Array.erase(me.bindings, i, 1); return; } } } } }, processKeys: function(keyCode) { var processed = false, key, keys, keyString, len, i; if (keyCode.test) { return keyCode; } if (Ext.isString(keyCode)) { keys = []; keyString = keyCode.toUpperCase(); for (i = 0 , len = keyString.length; i < len; ++i) { keys.push(keyString.charCodeAt(i)); } keyCode = keys; processed = true; } if (!Ext.isArray(keyCode)) { keyCode = [ keyCode ]; } if (!processed) { for (i = 0 , len = keyCode.length; i < len; ++i) { key = keyCode[i]; if (Ext.isString(key)) { keyCode[i] = key.toUpperCase().charCodeAt(0); } } } return keyCode; }, handleTargetEvent: function(event) { var me = this, bindings, i, len; if (me.enabled) { bindings = me.bindings; i = 0; len = bindings.length; event = me.processEvent.apply(me.processEventScope || me, arguments); if (event) { me.lastKeyEvent = event; if (me.ignoreInputFields && Ext.fly(event.target).isInputField()) { return; } if (!event.getKey) { return event; } me.processing = true; for (; i < len; ++i) { me.processBinding(bindings[i], event); } me.processing = false; } } }, processEvent: Ext.identityFn, 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; if (keyCode.test) { if (keyCode.test(String.fromCharCode(event.getCharCode()))) { if (handler.call(scope, key, event) !== true && defaultEventAction) { event[defaultEventAction](); } } } else if (keyCode.length) { for (i = 0 , len = keyCode.length; i < len; ++i) { if (key === keyCode[i]) { if (handler.call(scope, key, event) !== true && defaultEventAction) { event[defaultEventAction](); } break; } } } } }, checkModifiers: function(binding, event) { 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 === event[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 }); }, un: 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.removeBinding({ key: keyCode, shift: shift, ctrl: ctrl, alt: alt, fn: fn, scope: scope }); }, isEnabled: function() { return this.enabled; }, enable: function() { var me = this; if (!me.enabled) { me.target.on(me.eventName, me.handleTargetEvent, me, { capture: me.capture }); me.enabled = true; } }, disable: function() { var me = this; if (me.enabled) { me.target.removeListener(me.eventName, me.handleTargetEvent, me); me.enabled = false; } }, setDisabled: function(disabled) { if (disabled) { this.disable(); } else { this.enable(); } }, destroy: function(removeTarget) { var me = this, target = me.target; me.bindings = []; me.disable(); if (removeTarget) { target.destroy(); } delete me.target; } }); Ext.define('Ext.util.KeyNav', { alternateClassName: 'Ext.KeyNav', requires: [ 'Ext.util.KeyMap' ], disabled: false, defaultEventAction: false, forceKeyDown: false, eventName: 'keypress', 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(config) { var me = this; if (arguments.length === 2) { me.legacyConstructor.apply(me, arguments); return; } me.doConstruction(config); }, legacyConstructor: function(el, config) { this.doConstruction(Ext.apply({ target: el }, config)); }, doConstruction: function(config) { var me = this, keymapCfg = { target: config.target, ignoreInputFields: config.ignoreInputFields, eventName: me.getKeyEvent('forceKeyDown' in config ? config.forceKeyDown : me.forceKeyDown, config.eventName), capture: config.capture }, map; if (me.map) { me.map.destroy(); } me.initConfig(config); if (config.processEvent) { keymapCfg.processEvent = config.processEvent; keymapCfg.processEventScope = config.processEventScope || me; } if (config.keyMap) { map = me.map = config.keyMap; } else { map = me.map = new Ext.util.KeyMap(keymapCfg); me.destroyKeyMap = true; } this.addBindings(config); map.disable(); if (!config.disabled) { map.enable(); } }, addBindings: function(bindings) { var me = this, keyName, binding, map = me.map, keyCodes = Ext.util.KeyNav.keyOptions, defaultScope = bindings.scope || me; for (keyName in bindings) { binding = bindings[keyName]; if (binding && (keyName.length === 1 || (keyName = keyCodes[keyName]) || (!isNaN(keyName = parseInt(keyName, 10))))) { if (typeof binding === 'function') { binding = { handler: binding, defaultEventAction: (bindings.defaultEventAction !== undefined) ? bindings.defaultEventAction : me.defaultEventAction }; } map.addBinding({ key: keyName, ctrl: binding.ctrl, shift: binding.shift, alt: binding.alt, handler: Ext.Function.bind(me.handleEvent, binding.scope || defaultScope, [ binding.handler || binding.fn, me ], true), defaultEventAction: (binding.defaultEventAction !== undefined) ? binding.defaultEventAction : me.defaultEventAction }); } } }, handleEvent: function(keyCode, event, handler, keyNav) { keyNav.lastKeyEvent = event; return handler.call(this, event); }, destroy: function(removeEl) { if (this.destroyKeyMap) { this.map.destroy(removeEl); } delete this.map; }, enable: function() { if (this.map) { this.map.enable(); this.disabled = false; } }, disable: function() { if (this.map) { this.map.disable(); } this.disabled = true; }, setDisabled: function(disabled) { this.map.setDisabled(disabled); this.disabled = disabled; }, getKeyEvent: function(forceKeyDown, configuredEventName) { if (forceKeyDown || (Ext.supports.SpecialKeyDownRepeat && !configuredEventName)) { return 'keydown'; } else { return configuredEventName || this.eventName; } } }); Ext.define('Ext.util.FocusableContainer', { extend: 'Ext.Mixin', requires: [ 'Ext.util.KeyNav' ], mixinConfig: { id: 'focusablecontainer', before: { onAdd: 'onFocusableChildAdd', onRemove: 'onFocusableChildRemove', destroy: 'destroyFocusableContainer', onFocusEnter: 'onFocusEnter' }, after: { afterRender: 'initFocusableContainer', onFocusLeave: 'onFocusLeave' } }, isFocusableContainer: true, enableFocusableContainer: true, activeChildTabIndex: 0, inactiveChildTabIndex: -1, privates: { initFocusableContainer: function() { if (this.enableFocusableContainer) { this.doInitFocusableContainer(); } }, doInitFocusableContainer: function() { var me = this, el; el = me.getFocusableContainerEl(); me.activateFocusableContainerEl(el); me.mon(el, 'mousedown', me.onFocusableContainerMousedown, me); me.focusableKeyNav = me.createFocusableContainerKeyNav(el); }, createFocusableContainerKeyNav: function(el) { var me = this; return new Ext.util.KeyNav(el, { ignoreInputFields: true, scope: me, tab: me.onFocusableContainerTabKey, enter: me.onFocusableContainerEnterKey, space: me.onFocusableContainerSpaceKey, up: me.onFocusableContainerUpKey, down: me.onFocusableContainerDownKey, left: me.onFocusableContainerLeftKey, right: me.onFocusableContainerRightKey }); }, destroyFocusableContainer: function() { if (this.enableFocusableContainer) { this.doDestroyFocusableContainer(); } }, doDestroyFocusableContainer: function() { var keyNav = this.focusableKeyNav; if (keyNav) { keyNav.destroy(); delete this.focusableKeyNav; } }, getFocusables: function() { return this.items.items; }, initDefaultFocusable: function(beforeRender) { var me = this, activeIndex = me.activeChildTabIndex, haveFocusable = false, items, item, i, len, tabIdx; items = me.getFocusables(); len = items.length; if (!len) { return; } for (i = 0; i < len; i++) { item = items[i]; if (item.focusable) { haveFocusable = true; tabIdx = item.getTabIndex(); if (tabIdx != null && tabIdx >= activeIndex) { return item; } } } if (!haveFocusable) { return; } item = me.findNextFocusableChild(null, true, items, beforeRender); if (item) { me.activateFocusable(item); } return item; }, clearFocusables: function() { var me = this, items = me.getFocusables(), len = items.length, item, i; for (i = 0; i < len; i++) { item = items[i]; if (item.focusable) { me.deactivateFocusable(item); } } }, activateFocusable: function(child, newTabIndex) { var activeIndex = newTabIndex != null ? newTabIndex : this.activeChildTabIndex; child.setTabIndex(activeIndex); }, deactivateFocusable: function(child, newTabIndex) { var inactiveIndex = newTabIndex != null ? newTabIndex : this.inactiveChildTabIndex; child.setTabIndex(inactiveIndex); }, onFocusableContainerTabKey: function() { return true; }, onFocusableContainerEnterKey: function() { return true; }, onFocusableContainerSpaceKey: function() { return true; }, onFocusableContainerUpKey: function(e) { return this.moveChildFocus(e, false); }, onFocusableContainerLeftKey: function(e) { return this.moveChildFocus(e, false); }, onFocusableContainerRightKey: function(e) { return this.moveChildFocus(e, true); }, onFocusableContainerDownKey: function(e) { return this.moveChildFocus(e, true); }, getFocusableFromEvent: function(e) { var child = Ext.Component.fromElement(e.getTarget()); if (!child) { Ext.Error.raise("No focusable child found for keyboard event!"); } return child; }, moveChildFocus: function(e, forward) { var child = this.getFocusableFromEvent(e); return this.focusChild(child, forward, e); }, focusChild: function(child, forward) { var nextChild = this.findNextFocusableChild(child, forward); if (nextChild) { nextChild.focus(); } return nextChild; }, findNextFocusableChild: function(child, step, items, beforeRender) { var item, idx, i, len; items = items || this.getFocusables(); idx = Ext.Array.indexOf(items, child); step = step === true ? 1 : step === false ? -1 : step; len = items.length; i = step > 0 ? (idx < len ? idx + step : 0) : (idx > 0 ? idx + step : len - 1); for (; ; i += step) { if (idx < 0 && (i >= len || i < 0)) { return null; } else if (i >= len) { i = -1; continue; } else if (i < 0) { i = len; continue; } else if (i === idx) { return null; } item = items[i]; if (!item || !item.focusable) { continue; } if (beforeRender || (item.isFocusable && item.isFocusable())) { return item; } } return null; }, getFocusableContainerEl: function() { return this.el; }, onFocusableChildAdd: function(child) { return this.doFocusableChildAdd(child); }, activateFocusableContainerEl: function(el) { el = el || this.getFocusableContainerEl(); el.set({ tabindex: this.activeChildTabIndex }); }, deactivateFocusableContainerEl: function(el) { el = el || this.getFocusableContainerEl(); el.set({ tabindex: this.inactiveChildTabIndex }); }, doFocusableChildAdd: function(child) { if (child.focusable) { child.focusableContainer = this; this.deactivateFocusable(child); } }, onFocusableChildRemove: function(child) { return this.doFocusableChildRemove(child); }, doFocusableChildRemove: function(child) { if (child === this.lastFocusedChild) { this.lastFocusedChild = null; this.activateFocusableContainerEl(); } delete child.focusableContainer; }, onFocusableContainerMousedown: function(e, target) { var targetCmp = Ext.Component.fromElement(target); this.mousedownTimestamp = targetCmp === this ? Ext.Date.now() : 0; }, onFocusEnter: function(e) { var me = this, target = e.toComponent, mousedownTimestamp = me.mousedownTimestamp, epsilon = 50, child; me.mousedownTimestamp = 0; if (target === me) { if (!mousedownTimestamp || Ext.Date.now() - mousedownTimestamp > epsilon) { child = me.initDefaultFocusable(); if (child) { me.deactivateFocusableContainerEl(); child.focus(); } } } else { me.deactivateFocusableContainerEl(); } return target; }, onFocusLeave: function(e) { var me = this, lastFocused = me.lastFocusedChild; if (!me.isDestroyed) { me.clearFocusables(); if (lastFocused) { me.activateFocusable(lastFocused); } else { me.activateFocusableContainerEl(); } } }, beforeFocusableChildBlur: Ext.privateFn, afterFocusableChildBlur: Ext.privateFn, beforeFocusableChildFocus: function(child) { var me = this; me.clearFocusables(); me.activateFocusable(child); if (child.needArrowKeys) { me.guardFocusableChild(child); } }, guardFocusableChild: function(child) { var me = this, index = me.activeChildTabIndex, guard; guard = me.findNextFocusableChild(child, -1); if (guard) { guard.setTabIndex(index); } guard = me.findNextFocusableChild(child, 1); if (guard) { guard.setTabIndex(index); } }, afterFocusableChildFocus: function(child) { this.lastFocusedChild = child; }, onFocusableChildShow: Ext.privateFn, onFocusableChildHide: Ext.privateFn, onFocusableChildEnable: Ext.privateFn, onFocusableChildDisable: Ext.privateFn, onFocusableChildMasked: Ext.privateFn, onFocusableChildDestroy: Ext.privateFn, onFocusableChildUpdate: Ext.privateFn } }); Ext.define('Ext.toolbar.Toolbar', { extend: 'Ext.container.Container', requires: [ 'Ext.layout.container.HBox', 'Ext.layout.container.VBox' ], uses: [ 'Ext.toolbar.Fill', 'Ext.toolbar.Separator' ], alias: 'widget.toolbar', alternateClassName: 'Ext.Toolbar', mixins: [ 'Ext.util.FocusableContainer' ], isToolbar: true, baseCls: Ext.baseCSSPrefix + 'toolbar', ariaRole: 'toolbar', defaultType: 'button', layout: undefined, vertical: undefined, enableOverflow: false, overflowHandler: null, defaultButtonUI: 'default-toolbar', defaultFieldUI: 'default', defaultFooterButtonUI: 'default', defaultFooterFieldUI: 'default', trackMenus: true, itemCls: Ext.baseCSSPrefix + 'toolbar-item', statics: { shortcuts: { '-': 'tbseparator', ' ': 'tbspacer' }, shortcutsHV: { 0: { '->': { xtype: 'tbfill', height: 0 } }, 1: { '->': { xtype: 'tbfill', width: 0 } } } }, initComponent: function() { var me = this, layout = me.layout, vertical = me.vertical; if (vertical === undefined) { me.vertical = vertical = me.dock === 'right' || me.dock === 'left'; } me.layout = layout = Ext.applyIf(Ext.isString(layout) ? { type: layout } : layout || {}, { type: vertical ? 'vbox' : 'hbox', align: vertical ? 'stretchmax' : 'middle' }); if (me.overflowHandler) { layout.overflowHandler = me.overflowHandler; } else if (me.enableOverflow) { layout.overflowHandler = 'menu'; } if (vertical) { me.addClsWithUI('vertical'); } if (me.ui === 'footer') { me.ignoreBorderManagement = true; } me.callParent(); }, getRefItems: function(deep) { var me = this, items = me.callParent(arguments), layout = me.layout, handler; if (deep && (me.enableOverflow || (me.overflowHandler === 'menu'))) { handler = layout.overflowHandler; if (handler && handler.menu) { items = items.concat(handler.menu.getRefItems(deep)); } } return items; }, lookupComponent: function(c) { var args = arguments, shortcut, T; if (typeof c === 'string') { T = Ext.toolbar.Toolbar; shortcut = T.shortcutsHV[this.vertical ? 1 : 0][c] || T.shortcuts[c]; if (typeof shortcut === 'string') { c = { xtype: shortcut }; } else if (shortcut) { c = Ext.apply({}, shortcut); } else { c = { xtype: 'tbtext', text: c }; } this.applyDefaults(c); args = [ c ]; } return this.callParent(args); }, onBeforeAdd: function(component) { var me = this, isFooter = me.ui === 'footer', defaultButtonUI = isFooter ? me.defaultFooterButtonUI : me.defaultButtonUI; if (component.isSegmentedButton) { if (component.getDefaultUI() === 'default' && !component.config.hasOwnProperty('defaultUI')) { component.setDefaultUI(defaultButtonUI); } } else if (component.ui === 'default' && !component.hasOwnProperty('ui')) { if (component.isButton) { component.ui = defaultButtonUI; } else if (component.isFormField) { component.ui = isFooter ? me.defaultFooterFieldUI : me.defaultFieldUI; } } if (component instanceof Ext.toolbar.Separator) { component.setUI(me.vertical ? 'vertical' : 'horizontal'); } me.callParent(arguments); }, onAdd: function(component) { this.callParent(arguments); this.trackMenu(component); }, onRemove: function(c) { this.callParent(arguments); this.trackMenu(c, true); }, privates: { applyDefaults: function(c) { if (!Ext.isString(c)) { c = this.callParent(arguments); } return c; }, trackMenu: function(item, remove) { var me = this; if (me.trackMenus && item.menu) { item[remove ? 'un' : 'on']({ mouseover: me.onButtonOver, menushow: me.onButtonMenuShow, menuhide: me.onButtonMenuHide, scope: me }); } }, getChildItemsToDisable: function() { return this.items.getRange(); }, onButtonOver: function(btn, e) { var activeMenuBtn = this.activeMenuBtn; if (activeMenuBtn && activeMenuBtn !== btn) { activeMenuBtn.hideMenu(); btn.focus(); btn.showMenu(e); this.activeMenuBtn = btn; } }, onButtonMenuShow: function(btn) { this.activeMenuBtn = btn; }, onButtonMenuHide: function(btn) { this.activeMenuBtn = null; } } }); 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, triggerEvent: 'mousedown', 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 ddBox = Ext.get(this.getEl()).getBox(), constrainEl = Ext.get(constrainTo), s = constrainEl.getScroll(), c, constrainDom = constrainEl.dom, xy, topSpace, leftSpace; if (constrainDom === document.body) { c = { x: s.left, y: s.top, width: Ext.Element.getViewportWidth(), height: Ext.Element.getViewportHeight() }; } else { xy = constrainEl.getXY(); c = { x: xy[0], y: xy[1], width: constrainDom.clientWidth, height: constrainDom.clientHeight }; } topSpace = ddBox.y - c.y; leftSpace = ddBox.x - c.x; this.resetConstraints(); this.setXConstraint(leftSpace - (pad.left || 0), c.width - leftSpace - ddBox.width - (pad.right || 0), this.xTickSize); this.setYConstraint(topSpace - (pad.top || 0), c.height - topSpace - ddBox.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) { var me = this; me.el = me.el || Ext.get(id); me.initTarget(id, sGroup, config); Ext.get(me.id).on(me.triggerEvent, me.handleMouseDown, me); }, 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(), dx, dy, p; if (!this.DDMInstance.verifyEl(el)) { return; } dx = diffX || 0; dy = diffY || 0; p = Ext.fly(el).getXY(); 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.fly(this.getEl()).getXY(); 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.get(id).on(this.triggerEvent, this.handleMouseDown, this); this.setHandleElId(id); this.hasOuterHandles = true; }, unreg: function() { var me = this, el; if (me._domRef) { el = Ext.fly(me.id); if (el) { el.un(me.triggerEvent, me.handleMouseDown, me); } } me._domRef = null; me.DDMInstance._remove(me, me.autoGroup); }, destroy: function() { this.unreg(); this.isDestroyed = true; }, isLocked: function() { return (this.DDMInstance.isLocked() || this.locked); }, handleMouseDown: function(e, oDD) { var me = this; if ((me.primaryButtonOnly && e.button) || me.isLocked()) { return; } me.DDMInstance.refreshCache(me.groups); if (me.hasOuterHandles || me.DDMInstance.isOverTarget(e.getPoint(), me)) { if (me.clickValidator(e)) { me.setStartPosition(); me.b4MouseDown(e); me.onMouseDown(e); me.DDMInstance.handleMouseDown(e, me); me.DDMInstance.stopEvent(e); } } }, 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) { var invalidHandleClasses = this.invalidHandleClasses, len = invalidHandleClasses.length, i; for (i = 0; i < len; ++i) { if (invalidHandleClasses[i] === cssClass) { delete invalidHandleClasses[i]; } } }, isValidHandleChild: function(node) { var valid = true, nodeName, i, len; try { nodeName = node.nodeName.toUpperCase(); } catch (e) { nodeName = node.nodeName; } valid = valid && !this.invalidHandleTypes[nodeName]; valid = valid && !this.invalidHandleIds[node.id]; for (i = 0 , len = this.invalidHandleClasses.length; valid && i < len; ++i) { valid = !Ext.fly(node).hasCls(this.invalidHandleClasses[i]); } return valid; }, setXTicks: function(iStartX, iTickSize) { this.xTicks = []; this.xTickSize = iTickSize; var tickMap = {}, i; for (i = this.initPageX; 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 = {}, i; for (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, 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 { var i, len, next, diff1, diff2; for (i = 0 , len = tickArray.length; i < len; ++i) { next = i + 1; if (tickArray[next] && tickArray[next] >= val) { diff1 = val - tickArray[i]; 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, 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.Element, vpSize, aCoord, newLeft, newTop; if (!this.deltaSetXY) { vpSize = this.cachedViewportSize = { width: EL.getDocumentWidth(), height: EL.getDocumentHeight() }; 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); newLeft = this.getLocalX(fly); newTop = fly.getLocalY(); this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ]; } else { vpSize = this.cachedViewportSize; this.setLocalXY(fly, 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.fly(this.getEl()).getXY(); this.lastPageX = aCoord[0]; this.lastPageY = aCoord[1]; } }, autoScroll: function(x, y, h, w) { if (this.scroll) { var clientH = Ext.Element.getViewportHeight(), clientW = Ext.Element.getViewportWidth(), st = this.DDMInstance.getScrollTop(), sl = this.DDMInstance.getScrollLeft(), bot = h + y, right = w + x, toBot = (clientH + st - y - this.deltaY), toRight = (clientW + sl - x - this.deltaX), thresh = 40, 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, 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) { var xy = e.getXY(); this.autoOffset(xy[0], xy[1]); }, b4Drag: function(e) { var xy = e.getXY(); this.setDragElPos(xy[0], xy[1]); }, toString: function() { return ("DD " + this.id); }, getLocalX: function(el) { return el.getLocalX(); }, setLocalXY: function(el, x, y) { el.setLocalXY(x, y); } }); 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, body = document.body, div, s; if (!body || !body.firstChild) { Ext.defer(function() { self.createFrame(); }, 50); return; } div = this.getDragEl(); if (!div) { div = document.createElement("div"); div.id = this.dragElId; div.setAttribute('role', 'presentation'); 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 me = this, dragEl = me.getDragEl(), s = dragEl.style; me._resizeProxy(); if (me.centerFrame) { me.setDelta(Math.round(parseInt(s.width, 10) / 2), Math.round(parseInt(s.height, 10) / 2)); } me.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 xy = e.getXY(), x = xy[0], y = xy[1]; 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(), 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.StatusProxy', { extend: 'Ext.Component', animRepair: false, childEls: [ 'ghost' ], renderTpl: [ '' + '' ], repairCls: Ext.baseCSSPrefix + 'dd-drag-repair', ariaRole: 'presentation', constructor: function(config) { var me = this; config = config || {}; Ext.apply(me, { hideMode: 'visibility', hidden: true, floating: true, id: me.id || Ext.id(), cls: Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed, shadow: config.shadow || false, renderTo: Ext.getDetachedBody() }); me.callParent(arguments); 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) { var me = this, clsPrefix = Ext.baseCSSPrefix + 'dd-drag-proxy '; me.el.replaceCls(clsPrefix + me.dropAllowed, clsPrefix + me.dropNotAllowed); me.dropStatus = me.dropNotAllowed; if (clearGhost) { me.ghost.setHtml(''); } }, update: function(html) { if (typeof html === "string") { this.ghost.setHtml(html); } else { this.ghost.setHtml(''); html.style.margin = "0"; this.ghost.dom.appendChild(html); } var el = this.ghost.dom.firstChild; if (el) { Ext.fly(el).setStyle('float', 'none'); } }, getGhost: function() { return this.ghost; }, hide: function(clear) { this.callParent(); if (clear) { this.reset(true); } }, stop: function() { if (this.anim && this.anim.isAnimated && this.anim.isAnimated()) { this.anim.stop(); } }, sync: function() { this.el.syncUnderlays(); }, repair: function(xy, callback, scope) { var me = this; me.callback = callback; me.scope = scope; if (xy && me.animRepair !== false) { me.el.addCls(me.repairCls); me.el.setUnderlaysVisible(false); me.anim = me.el.animate({ duration: me.repairDuration || 500, easing: 'ease-out', to: { x: xy[0], y: xy[1] }, stopAnimation: true, callback: me.afterRepair, scope: me }); } else { me.afterRepair(); } }, afterRepair: function() { var me = this; me.hide(true); me.el.removeCls(me.repairCls); if (typeof me.callback === "function") { me.callback.call(me.scope || me); } delete me.callback; delete me.scope; } }); 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 = new Ext.dd.StatusProxy({ id: this.el.id + '-drag-status-proxy', 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), status; this.cachedTarget = target; if (this.beforeDragEnter(target, e, id) !== false) { if (target.isNotifyTarget) { 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; }, onDragOver: function(e, id) { var target = this.cachedTarget || Ext.dd.DragDropManager.getDDById(id), status; if (this.beforeDragOver(target, e, id) !== false) { if (target.isNotifyTarget) { 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) { var me = this; if (!e) { e = target; target = null; id = e.getTarget().id; } if (me.beforeInvalidDrop(target, e, id) !== false) { if (me.cachedTarget) { if (me.cachedTarget.isNotifyTarget) { me.cachedTarget.notifyOut(me, e, me.dragData); } me.cacheTarget = null; } me.proxy.repair(me.getRepairXY(e, me.dragData), me.afterRepair, me); if (me.afterInvalidDrop) { me.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, alignElWithMouse: function() { this.proxy.ensureAttachedToBody(true); return this.callParent(arguments); }, startDrag: function(x, y) { this.proxy.reset(); this.proxy.hidden = false; 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.Proxy', { alternateClassName: 'Ext.dd.PanelProxy', moveOnDrag: true, constructor: function(panel, config) { var me = this; me.panel = panel; me.id = me.panel.id + '-ddproxy'; Ext.apply(me, 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() { var me = this; if (me.ghost) { if (me.proxy) { me.proxy.destroy(); delete me.proxy; } me.panel.unghost(null, me.moveOnDrag); delete me.ghost; } }, show: function() { var me = this, panelSize; if (!me.ghost) { panelSize = me.panel.getSize(); me.panel.el.setVisibilityMode(Ext.Element.DISPLAY); me.ghost = me.panel.ghost(); if (me.insertProxy) { me.proxy = me.panel.el.insertSibling({ role: 'presentation', cls: Ext.baseCSSPrefix + 'panel-dd-spacer' }); me.proxy.setSize(panelSize); } } }, repair: function(xy, callback, scope) { this.hide(); Ext.callback(callback, scope || this); }, moveProxy: function(parentNode, before) { if (this.proxy) { parentNode.insertBefore(this.proxy.dom, before); } } }); Ext.define('Ext.panel.DD', { extend: 'Ext.dd.DragSource', requires: [ 'Ext.panel.Proxy' ], constructor: function(panel, cfg) { var me = this; me.panel = panel; me.dragData = { panel: panel }; me.panelProxy = new Ext.panel.Proxy(panel, cfg); me.proxy = me.panelProxy.proxy; me.callParent([ panel.el, cfg ]); me.setupEl(panel); }, setupEl: function(panel) { var me = this, header = panel.header, el = panel.body; if (header) { me.setHandleElId(header.id); el = header.el; } if (el) { el.setStyle('cursor', 'move'); me.scroll = false; } else { panel.on('boxready', me.setupEl, me, { single: true }); } }, showFrame: Ext.emptyFn, startDrag: Ext.emptyFn, b4StartDrag: function(x, y) { this.panelProxy.show(); }, b4MouseDown: function(e) { var xy = e.getXY(), x = xy[0], y = xy[1]; this.autoOffset(x, y); }, onInitDrag: function(x, y) { this.onStartDrag(x, y); return true; }, createFrame: Ext.emptyFn, getDragEl: function(e) { var ghost = this.panelProxy.ghost; if (ghost) { return ghost.el.dom; } }, endDrag: function(e) { this.panelProxy.hide(); this.panel.saveState(); }, autoOffset: function(x, y) { x -= this.startPageX; y -= this.startPageY; this.setDelta(x, y); }, onInvalidDrop: function(target, e, id) { var me = this; if (me.beforeInvalidDrop(target, e, id) !== false) { if (me.cachedTarget) { if (me.cachedTarget.isNotifyTarget) { me.cachedTarget.notifyOut(me, e, me.dragData); } me.cacheTarget = null; } if (me.afterInvalidDrop) { me.afterInvalidDrop(e, id); } } } }); Ext.define('Ext.layout.component.Dock', { extend: 'Ext.layout.component.Component', alias: 'layout.dock', alternateClassName: 'Ext.layout.component.AbstractDock', type: 'dock', horzAxisProps: { name: 'horz', oppositeName: 'vert', dockBegin: 'left', dockEnd: 'right', horizontal: true, marginBegin: 'margin-left', maxSize: 'maxWidth', minSize: 'minWidth', pos: 'x', setSize: 'setWidth', shrinkWrapDock: 'shrinkWrapDockWidth', size: 'width', sizeModel: 'widthModel' }, vertAxisProps: { name: 'vert', oppositeName: 'horz', dockBegin: 'top', dockEnd: 'bottom', horizontal: false, marginBegin: 'margin-top', maxSize: 'maxHeight', minSize: 'minHeight', pos: 'y', setSize: 'setHeight', shrinkWrapDock: 'shrinkWrapDockHeight', size: 'height', sizeModel: 'heightModel' }, initializedBorders: -1, horizontalCollapsePolicy: { width: true, x: true }, verticalCollapsePolicy: { height: true, y: true }, finishRender: function() { var me = this, target, items; me.callParent(); target = me.getRenderTarget(); items = me.getDockedItems(); me.finishRenderItems(target, items); }, isItemBoxParent: function(itemContext) { return true; }, isItemShrinkWrap: function(item) { return true; }, noBorderClasses: [ Ext.baseCSSPrefix + 'docked-noborder-top', Ext.baseCSSPrefix + 'docked-noborder-right', Ext.baseCSSPrefix + 'docked-noborder-bottom', Ext.baseCSSPrefix + 'docked-noborder-left' ], noBorderClassesSides: { top: Ext.baseCSSPrefix + 'docked-noborder-top', right: Ext.baseCSSPrefix + 'docked-noborder-right', bottom: Ext.baseCSSPrefix + 'docked-noborder-bottom', left: Ext.baseCSSPrefix + 'docked-noborder-left' }, borderWidthProps: { top: 'border-top-width', right: 'border-right-width', bottom: 'border-bottom-width', left: 'border-left-width' }, _itemCls: Ext.baseCSSPrefix + 'docked', handleItemBorders: function() { var me = this, owner = me.owner, borders, docked, lastItems = me.lastDockedItems, oldBorders = me.borders, currentGeneration = owner.dockedItems.generation, noBorderClassesSides = me.noBorderClassesSides, borderWidthProps = me.borderWidthProps, i, ln, item, dock, side, collapsed = me.collapsed; if (me.initializedBorders === currentGeneration || (owner.border && !owner.manageBodyBorders) || (owner.collapsed && owner.collapseMode === 'mini')) { return; } me.initializedBorders = currentGeneration; me.collapsed = false; me.lastDockedItems = docked = me.getLayoutItems(); me.collapsed = collapsed; borders = { top: [], right: [], bottom: [], left: [] }; 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 && dock !== 'bottom') { borders.top.push(item); } if (!borders.right.satisfied && dock !== 'left') { borders.right.push(item); } if (!borders.bottom.satisfied && dock !== 'top') { borders.bottom.push(item); } if (!borders.left.satisfied && dock !== 'right') { borders.left.push(item); } } if (lastItems) { for (i = 0 , ln = lastItems.length; i < ln; i++) { item = lastItems[i]; if (!item.isDestroyed && !item.ignoreBorderManagement && !owner.manageBodyBorders) { item.removeCls(me.noBorderClasses); } } } if (oldBorders) { for (side in oldBorders) { if (owner.manageBodyBorders && oldBorders[side].satisfied) { owner.setBodyStyle(borderWidthProps[side], ''); } } } for (side in borders) { ln = borders[side].length; if (!owner.manageBodyBorders) { for (i = 0; i < ln; i++) { borders[side][i].addCls(noBorderClassesSides[side]); } if ((!borders[side].satisfied && !owner.bodyBorder) || owner.bodyBorder === false) { owner.addBodyCls(noBorderClassesSides[side]); } else { owner.removeBodyCls(noBorderClassesSides[side]); } } else if (borders[side].satisfied) { owner.setBodyStyle(borderWidthProps[side], '1px'); } } me.borders = borders; }, beforeLayoutCycle: function(ownerContext) { var me = this, owner = me.owner, shrinkWrap = me.sizeModels.shrinkWrap, shrinkWrapDock = owner.shrinkWrapDock, collapsedHorz, collapsedVert; if (owner.collapsed) { if (owner.collapsedVertical()) { collapsedVert = true; ownerContext.measureDimensions = 1; } else { collapsedHorz = true; ownerContext.measureDimensions = 2; } } ownerContext.collapsedVert = collapsedVert; ownerContext.collapsedHorz = collapsedHorz; if (collapsedVert) { ownerContext.heightModel = shrinkWrap; } else if (collapsedHorz) { ownerContext.widthModel = shrinkWrap; } shrinkWrapDock = shrinkWrapDock === true ? 3 : (shrinkWrapDock || 0); ownerContext.shrinkWrapDockHeight = (shrinkWrapDock & 1) && ownerContext.heightModel.shrinkWrap; ownerContext.shrinkWrapDockWidth = (shrinkWrapDock & 2) && ownerContext.widthModel.shrinkWrap; }, beginLayout: function(ownerContext) { var me = this, owner = me.owner, docked = me.getLayoutItems(), layoutContext = ownerContext.context, dockedItemCount = docked.length, lastCollapsedState = me.lastCollapsedState, dockedItems, i, item, itemContext, offsets, collapsed, dock; me.callParent(arguments); collapsed = owner.getCollapsed(); if (collapsed !== lastCollapsedState && lastCollapsedState !== undefined) { if (me.owner.collapsed) { ownerContext.isCollapsingOrExpanding = 1; owner.addClsWithUI(owner.collapsedCls); } else { ownerContext.isCollapsingOrExpanding = 2; owner.removeClsWithUI(owner.collapsedCls); ownerContext.lastCollapsedState = me.lastCollapsedState; } } me.lastCollapsedState = collapsed; ownerContext.dockedItems = dockedItems = []; for (i = 0; i < dockedItemCount; i++) { item = docked[i]; if (item.rendered) { dock = item.dock; itemContext = layoutContext.getCmp(item); itemContext.dockedAt = { x: 0, y: 0 }; itemContext.offsets = offsets = Ext.Element.parseBox(item.offsets || 0); itemContext.horizontal = dock === 'top' || dock === 'bottom'; offsets.width = offsets.left + offsets.right; offsets.height = offsets.top + offsets.bottom; dockedItems.push(itemContext); } } ownerContext.bodyContext = ownerContext.getEl('body'); }, beginLayoutCycle: function(ownerContext) { var me = this, docked = ownerContext.dockedItems, len = docked.length, owner = me.owner, frameBody = owner.frameBody, lastHeightModel = me.lastHeightModel, i, item, dock; me.callParent(arguments); if (me.owner.manageHeight) { if (me.lastBodyDisplay) { owner.body.dom.style.display = me.lastBodyDisplay = ''; } } else { if (me.lastBodyDisplay !== 'inline-block') { owner.body.dom.style.display = me.lastBodyDisplay = 'inline-block'; } if (lastHeightModel && lastHeightModel.shrinkWrap && !ownerContext.heightModel.shrinkWrap) { owner.body.dom.style.marginBottom = ''; } } if (ownerContext.widthModel.auto) { if (ownerContext.widthModel.shrinkWrap) { owner.el.setWidth(null); } owner.body.setWidth(null); if (frameBody) { frameBody.setWidth(null); } } if (ownerContext.heightModel.auto) { owner.body.setHeight(null); if (frameBody) { frameBody.setHeight(null); } } if (ownerContext.collapsedVert) { ownerContext.setContentHeight(0); } else if (ownerContext.collapsedHorz) { ownerContext.setContentWidth(0); } for (i = 0; i < len; i++) { item = docked[i].target; dock = item.dock; if (dock === 'right') { item.setLocalX(0); } else if (dock !== 'left') { continue; } } }, calculate: function(ownerContext) { var me = this, measure = me.measureAutoDimensions(ownerContext, ownerContext.measureDimensions), state = ownerContext.state, horzDone = state.horzDone, vertDone = state.vertDone, bodyContext = ownerContext.bodyContext, framing, horz, vert, forward, backward; ownerContext.borderInfo || ownerContext.getBorderInfo(); ownerContext.paddingInfo || ownerContext.getPaddingInfo(); ownerContext.frameInfo || ownerContext.getFrameInfo(); bodyContext.borderInfo || bodyContext.getBorderInfo(); bodyContext.paddingInfo || bodyContext.getPaddingInfo(); if (!ownerContext.frameBorder) { if (!(framing = ownerContext.framing)) { ownerContext.frameBorder = ownerContext.borderInfo; ownerContext.framePadding = ownerContext.paddingInfo; } else { ownerContext.frameBorder = framing.border; ownerContext.framePadding = framing.padding; } } horz = !horzDone && me.createAxis(ownerContext, measure.contentWidth, ownerContext.widthModel, me.horzAxisProps, ownerContext.collapsedHorz); vert = !vertDone && me.createAxis(ownerContext, measure.contentHeight, ownerContext.heightModel, me.vertAxisProps, ownerContext.collapsedVert); for (forward = 0 , backward = ownerContext.dockedItems.length; backward--; ++forward) { if (horz) { me.dockChild(ownerContext, horz, backward, forward); } if (vert) { me.dockChild(ownerContext, vert, backward, forward); } } if (horz && me.finishAxis(ownerContext, horz)) { state.horzDone = horzDone = horz; } if (vert && me.finishAxis(ownerContext, vert)) { state.vertDone = vertDone = vert; } if (horzDone && vertDone && me.finishConstraints(ownerContext, horzDone, vertDone)) { me.finishPositions(ownerContext, horzDone, vertDone); } else { me.done = false; } }, createAxis: function(ownerContext, contentSize, sizeModel, axisProps, collapsedAxis) { var me = this, begin = 0, owner = me.owner, maxSize = owner[axisProps.maxSize], minSize = owner[axisProps.minSize] || 0, dockBegin = axisProps.dockBegin, dockEnd = axisProps.dockEnd, posProp = axisProps.pos, sizeProp = axisProps.size, hasMaxSize = maxSize != null, shrinkWrap = sizeModel.shrinkWrap, bodyContext, framing, padding, end; if (shrinkWrap) { if (collapsedAxis) { end = 0; } else { bodyContext = ownerContext.bodyContext; end = contentSize + bodyContext.borderInfo[sizeProp]; } } else { framing = ownerContext.frameBorder; padding = ownerContext.framePadding; begin = framing[dockBegin] + padding[dockBegin]; end = ownerContext.getProp(sizeProp) - (framing[dockEnd] + padding[dockEnd]); } return { shrinkWrap: sizeModel.shrinkWrap, sizeModel: sizeModel, initialBegin: begin, begin: begin, end: end, collapsed: collapsedAxis, horizontal: axisProps.horizontal, ignoreFrameBegin: null, ignoreFrameEnd: null, initialSize: end - begin, maxChildSize: 0, hasMinMaxConstraints: (minSize || hasMaxSize) && sizeModel.shrinkWrap, minSize: minSize, maxSize: hasMaxSize ? maxSize : 1000000000, bodyPosProp: me.owner.manageHeight ? posProp : axisProps.marginBegin, dockBegin: dockBegin, dockEnd: dockEnd, posProp: posProp, sizeProp: sizeProp, setSize: axisProps.setSize, shrinkWrapDock: ownerContext[axisProps.shrinkWrapDock], sizeModelName: axisProps.sizeModel, dockedPixelsEnd: 0 }; }, dockChild: function(ownerContext, axis, backward, forward) { var me = this, itemContext = ownerContext.dockedItems[axis.shrinkWrap ? backward : forward], item = itemContext.target, dock = item.dock, sizeProp = axis.sizeProp, pos, size; if (item.ignoreParentFrame && ownerContext.isCollapsingOrExpanding) { itemContext.clearMarginCache(); } if (!itemContext.marginInfo) { itemContext.getMarginInfo(); } if (dock === axis.dockBegin) { if (axis.shrinkWrap) { pos = me.dockOutwardBegin(ownerContext, itemContext, item, axis); } else { pos = me.dockInwardBegin(ownerContext, itemContext, item, axis); } } else if (dock === axis.dockEnd) { if (axis.shrinkWrap) { pos = me.dockOutwardEnd(ownerContext, itemContext, item, axis); } else { pos = me.dockInwardEnd(ownerContext, itemContext, item, axis); } } else { if (axis.shrinkWrapDock) { size = itemContext.getProp(sizeProp) + itemContext.marginInfo[sizeProp]; axis.maxChildSize = Math.max(axis.maxChildSize, size); pos = 0; } else { pos = me.dockStretch(ownerContext, itemContext, item, axis); } } itemContext.dockedAt[axis.posProp] = pos; }, dockInwardBegin: function(ownerContext, itemContext, item, axis) { var pos = axis.begin, sizeProp = axis.sizeProp, ignoreParentFrame = item.ignoreParentFrame, delta, size, dock; if (ignoreParentFrame) { axis.ignoreFrameBegin = itemContext; dock = item.dock; delta = ownerContext.frameBorder[dock]; pos -= delta + ownerContext.framePadding[dock]; } if (!item.overlay) { size = itemContext.getProp(sizeProp) + itemContext.marginInfo[sizeProp]; axis.begin += size; if (ignoreParentFrame) { axis.begin -= delta; } } return pos; }, dockInwardEnd: function(ownerContext, itemContext, item, axis) { var sizeProp = axis.sizeProp, size = itemContext.getProp(sizeProp) + itemContext.marginInfo[sizeProp], pos = axis.end - size, frameEnd; if (!item.overlay) { axis.end = pos; } if (item.ignoreParentFrame) { axis.ignoreFrameEnd = itemContext; frameEnd = ownerContext.frameBorder[item.dock]; pos += frameEnd + ownerContext.framePadding[item.dock]; axis.end += frameEnd; } return pos; }, dockOutwardBegin: function(ownerContext, itemContext, item, axis) { var pos = axis.begin, sizeProp = axis.sizeProp, size; if (axis.collapsed) { axis.ignoreFrameBegin = axis.ignoreFrameEnd = itemContext; } else if (item.ignoreParentFrame) { axis.ignoreFrameBegin = itemContext; } if (!item.overlay) { size = itemContext.getProp(sizeProp) + itemContext.marginInfo[sizeProp]; pos -= size; axis.begin = pos; } return pos; }, dockOutwardEnd: function(ownerContext, itemContext, item, axis) { var pos = axis.end, sizeProp = axis.sizeProp, size; size = itemContext.getProp(sizeProp) + itemContext.marginInfo[sizeProp]; if (axis.collapsed) { axis.ignoreFrameBegin = axis.ignoreFrameEnd = itemContext; } else if (item.ignoreParentFrame) { axis.ignoreFrameEnd = itemContext; } if (!item.overlay) { axis.end = pos + size; axis.dockedPixelsEnd += size; } return pos; }, dockStretch: function(ownerContext, itemContext, item, axis) { var dock = item.dock, sizeProp = axis.sizeProp, horizontal = dock === 'top' || dock === 'bottom', border = ownerContext.frameBorder, offsets = itemContext.offsets, padding = ownerContext.framePadding, endProp = horizontal ? 'right' : 'bottom', startProp = horizontal ? 'left' : 'top', pos = axis.begin + offsets[startProp], margin, size; if (item.stretch !== false) { size = axis.end - pos - offsets[endProp]; if (item.ignoreParentFrame) { pos -= padding[startProp] + border[startProp]; size += padding[sizeProp] + border[sizeProp]; } margin = itemContext.marginInfo; size -= margin[sizeProp]; itemContext[axis.setSize](size); } return pos; }, finishAxis: function(ownerContext, axis) { if (isNaN(axis.maxChildSize)) { return false; } var axisBegin = axis.begin, size = axis.end - axisBegin, collapsed = axis.collapsed, setSizeMethod = axis.setSize, beginName = axis.dockBegin, endName = axis.dockEnd, padding = ownerContext.framePadding, border = ownerContext.frameBorder, borderBegin = border[beginName], framing = ownerContext.framing, framingBegin = framing && framing[beginName], paddingBegin = collapsed ? 0 : padding[beginName], sizeProp = axis.sizeProp, ignoreFrameBegin = axis.ignoreFrameBegin, ignoreFrameEnd = axis.ignoreFrameEnd, bodyContext = ownerContext.bodyContext, extraPaddingBegin = Math.max(borderBegin + paddingBegin - framingBegin, 0), bodyPos, bodySize, delta, dirty; if (axis.shrinkWrap) { bodySize = axis.initialSize; if (framing) { delta = -axisBegin + borderBegin + paddingBegin; bodyPos = delta - framingBegin - extraPaddingBegin; } else { bodyPos = -axisBegin; delta = bodyPos + paddingBegin; } if (!collapsed) { size += padding[sizeProp]; } if (ignoreFrameBegin) { delta -= borderBegin; bodyPos -= borderBegin; ignoreFrameBegin.dockedAt[axis.posProp] -= paddingBegin; } else { size += borderBegin; } if (collapsed) {} else if (ignoreFrameEnd) { ignoreFrameEnd.dockedAt[axis.posProp] += padding[endName]; } else { size += border[endName]; } axis.size = size; if (!axis.horizontal && !this.owner.manageHeight) { dirty = false; } } else { if (framing) { delta = 0; bodyPos = axisBegin - framingBegin - extraPaddingBegin; } else { delta = -borderBegin; bodyPos = axisBegin - paddingBegin - borderBegin; } bodySize = size; } axis.delta = delta; bodyContext[setSizeMethod](bodySize, dirty); bodyContext.setProp(axis.bodyPosProp, bodyPos); return !isNaN(size); }, beforeInvalidateShrinkWrapDock: function(itemContext, options) { var sizeModelName = options.axis.sizeModelName; if (!itemContext[sizeModelName].constrainedMin) { itemContext[sizeModelName] = Ext.layout.SizeModel.calculated; } }, afterInvalidateShrinkWrapDock: function(itemContext, options) { var axis = options.axis, me = options.layout, pos; if (itemContext[axis.sizeModelName].calculated) { pos = me.dockStretch(options.ownerContext, itemContext, itemContext.target, axis); itemContext.setProp(axis.posProp, axis.delta + pos); } }, finishConstraints: function(ownerContext, horz, vert) { var me = this, sizeModels = me.sizeModels, publishWidth = horz.shrinkWrap, publishHeight = vert.shrinkWrap, owner = me.owner, dirty, height, width, heightModel, widthModel, size, minSize, maxSize, maxChildSize, desiredSize; if (publishWidth) { size = horz.size; minSize = horz.collapsed ? 0 : horz.minSize; maxSize = horz.maxSize; maxChildSize = horz.maxChildSize; desiredSize = Math.max(size, maxChildSize); if (desiredSize > maxSize) { widthModel = sizeModels.constrainedMax; width = maxSize; } else if (desiredSize < minSize) { widthModel = sizeModels.constrainedMin; width = minSize; } else if (size < maxChildSize) { widthModel = sizeModels.constrainedDock; owner.dockConstrainedWidth = width = maxChildSize; } else { width = size; } } if (publishHeight) { size = vert.size; minSize = vert.collapsed ? 0 : vert.minSize; maxSize = vert.maxSize; maxChildSize = vert.maxChildSize; desiredSize = Math.max(size, maxChildSize + size - vert.initialSize); if (desiredSize > maxSize) { heightModel = sizeModels.constrainedMax; height = maxSize; } else if (desiredSize < minSize) { heightModel = sizeModels.constrainedMin; height = minSize; } else if (size < maxChildSize) { heightModel = sizeModels.constrainedDock; owner.dockConstrainedHeight = height = maxChildSize; } else { if (!ownerContext.collapsedVert && !owner.manageHeight) { dirty = false; ownerContext.bodyContext.setProp('margin-bottom', vert.dockedPixelsEnd); } height = size; } } if (widthModel || heightModel) { if (widthModel && heightModel && widthModel.constrainedMax && heightModel.constrainedByMin) { ownerContext.invalidate({ widthModel: widthModel }); return false; } if (!ownerContext.widthModel.calculatedFromShrinkWrap && !ownerContext.heightModel.calculatedFromShrinkWrap) { ownerContext.invalidate({ widthModel: widthModel, heightModel: heightModel }); return false; } } else { me.invalidateAxes(ownerContext, horz, vert); } if (publishWidth) { ownerContext.setWidth(width); if (widthModel) { ownerContext.widthModel = widthModel; } } if (publishHeight) { ownerContext.setHeight(height, dirty); if (heightModel) { ownerContext.heightModel = heightModel; } } return true; }, invalidateAxes: function(ownerContext, horz, vert) { var before = this.beforeInvalidateShrinkWrapDock, after = this.afterInvalidateShrinkWrapDock, horzSize = horz.end - horz.begin, vertSize = vert.initialSize, invalidateHorz = horz.shrinkWrapDock && horz.maxChildSize <= horzSize, invalidateVert = vert.shrinkWrapDock && vert.maxChildSize <= vertSize, dockedItems, len, i, itemContext, itemSize, isHorz, axis, sizeProp; if (invalidateHorz || invalidateVert) { if (invalidateVert) { vert.begin = vert.initialBegin; vert.end = vert.begin + vert.initialSize; } dockedItems = ownerContext.dockedItems; for (i = 0 , len = dockedItems.length; i < len; ++i) { itemContext = dockedItems[i]; isHorz = itemContext.horizontal; axis = null; if (invalidateHorz && isHorz) { sizeProp = horz.sizeProp; itemSize = horzSize; axis = horz; } else if (invalidateVert && !isHorz) { sizeProp = vert.sizeProp; itemSize = vertSize; axis = vert; } if (axis) { itemSize -= itemContext.getMarginInfo()[sizeProp]; if (itemSize !== itemContext.props[sizeProp]) { itemContext.invalidate({ before: before, after: after, axis: axis, ownerContext: ownerContext, layout: this }); } } } } }, finishPositions: function(ownerContext, horz, vert) { var dockedItems = ownerContext.dockedItems, length = dockedItems.length, deltaX = horz.delta, deltaY = vert.delta, index, itemContext; for (index = 0; index < length; ++index) { itemContext = dockedItems[index]; itemContext.setProp('x', deltaX + itemContext.dockedAt.x); itemContext.setProp('y', deltaY + itemContext.dockedAt.y); } }, finishedLayout: function(ownerContext) { var me = this, target = ownerContext.target; me.callParent(arguments); if (!ownerContext.animatePolicy) { if (ownerContext.isCollapsingOrExpanding === 1) { target.afterCollapse(false); } else if (ownerContext.isCollapsingOrExpanding === 2) { target.afterExpand(false); } } }, getAnimatePolicy: function(ownerContext) { var me = this, lastCollapsedState, policy; if (ownerContext.isCollapsingOrExpanding === 1) { lastCollapsedState = me.lastCollapsedState; } else if (ownerContext.isCollapsingOrExpanding === 2) { lastCollapsedState = ownerContext.lastCollapsedState; } if (lastCollapsedState === 'left' || lastCollapsedState === 'right') { policy = me.horizontalCollapsePolicy; } else if (lastCollapsedState === 'top' || lastCollapsedState === 'bottom') { policy = me.verticalCollapsePolicy; } return policy; }, getDockedItems: function(order, beforeBody) { var me = this, renderedOnly = (order === 'visual'), all = renderedOnly ? Ext.ComponentQuery.query('[rendered]', me.owner.dockedItems.items) : me.owner.dockedItems.items, sort = all && all.length && order !== false, renderOrder, dock, dockedItems, i, isBefore, length; if (beforeBody == null) { dockedItems = sort && !renderedOnly ? all.slice() : all; } else { dockedItems = []; for (i = 0 , length = all.length; i < length; ++i) { dock = all[i].dock; isBefore = (dock === 'top' || dock === 'left'); if (beforeBody ? isBefore : !isBefore) { dockedItems.push(all[i]); } } sort = sort && dockedItems.length; } if (sort) { renderOrder = (order = order || 'render') === 'render'; Ext.Array.sort(dockedItems, function(a, b) { var aw, bw; if (renderOrder && ((aw = me.owner.dockOrder[a.dock]) !== (bw = me.owner.dockOrder[b.dock]))) { if (!(aw + bw)) { return aw - bw; } } aw = me.getItemWeight(a, order); bw = me.getItemWeight(b, order); if ((aw !== undefined) && (bw !== undefined)) { return aw - bw; } return 0; }); } return dockedItems || []; }, getItemWeight: function(item, order) { var weight = item.weight || this.owner.defaultDockWeights[item.dock]; return weight[order] || weight; }, getLayoutItems: function() { var me = this, items, itemCount, item, i, result; if (me.owner.collapsed) { result = me.owner.getCollapsedDockedItems(); } else { items = me.getDockedItems('visual'); itemCount = items.length; result = []; for (i = 0; i < itemCount; i++) { item = items[i]; if (!item.hidden) { result.push(item); } } } return result; }, measureContentWidth: function(ownerContext) { var bodyContext = ownerContext.bodyContext; return bodyContext.el.getWidth() - bodyContext.getBorderInfo().width; }, measureContentHeight: function(ownerContext) { var bodyContext = ownerContext.bodyContext; return bodyContext.el.getHeight() - bodyContext.getBorderInfo().height; }, redoLayout: function(ownerContext) { var me = this, owner = me.owner; if (ownerContext.isCollapsingOrExpanding === 1) { if (owner.reExpander) { owner.reExpander.el.show(); } owner.addClsWithUI(owner.collapsedCls); ownerContext.redo(true); } else if (ownerContext.isCollapsingOrExpanding === 2) { owner.removeClsWithUI(owner.collapsedCls); ownerContext.bodyContext.redo(); } }, renderChildren: function() { var me = this, items = me.getDockedItems(), target = me.getRenderTarget(); me.handleItemBorders(); me.renderItems(items, target); }, renderItems: function(items, target) { var me = this, dockedItemCount = items.length, itemIndex = 0, correctPosition = 0, staticNodeCount = 0, targetNodes = me.getRenderTarget().dom.childNodes, targetChildCount = targetNodes.length, i, j, targetChildNode, item; for (i = 0 , j = 0; i < targetChildCount; i++) { targetChildNode = targetNodes[i]; if (targetChildNode.nodeType === 1 && Ext.fly(targetChildNode).hasCls(Ext.baseCSSPrefix + 'resizable-handle')) { break; } for (j = 0; j < dockedItemCount; j++) { item = items[j]; if (item.rendered && item.el.dom === targetChildNode) { break; } } if (j === dockedItemCount) { staticNodeCount++; } } for (; itemIndex < dockedItemCount; itemIndex++ , correctPosition++) { item = items[itemIndex]; if (itemIndex === correctPosition && (item.dock === 'right' || item.dock === 'bottom')) { correctPosition += staticNodeCount; } if (item && !item.rendered) { me.renderItem(item, target, correctPosition); } else if (!me.isValidParent(item, target, correctPosition)) { me.moveItem(item, target, correctPosition); } } }, undoLayout: function(ownerContext) { var me = this, owner = me.owner; if (ownerContext.isCollapsingOrExpanding === 1) { if (owner.reExpander) { owner.reExpander.el.hide(); } owner.removeClsWithUI(owner.collapsedCls); ownerContext.undo(true); } else if (ownerContext.isCollapsingOrExpanding === 2) { owner.addClsWithUI(owner.collapsedCls); ownerContext.bodyContext.undo(); } }, sizePolicy: { nostretch: { setsWidth: 0, setsHeight: 0 }, horz: { shrinkWrap: { setsWidth: 1, setsHeight: 0, readsWidth: 1 }, stretch: { setsWidth: 1, setsHeight: 0 } }, vert: { shrinkWrap: { setsWidth: 0, setsHeight: 1, readsHeight: 1 }, stretch: { setsWidth: 0, setsHeight: 1 } }, stretchV: { setsWidth: 0, setsHeight: 1 }, autoStretchH: { readsWidth: 1, setsWidth: 1, setsHeight: 0 }, autoStretchV: { readsHeight: 1, setsWidth: 0, setsHeight: 1 } }, getItemSizePolicy: function(item, ownerSizeModel) { var me = this, policy = me.sizePolicy, shrinkWrapDock = me.owner.shrinkWrapDock, dock, vertical; if (item.stretch === false) { return policy.nostretch; } dock = item.dock; vertical = (dock === 'left' || dock === 'right'); shrinkWrapDock = shrinkWrapDock === true ? 3 : (shrinkWrapDock || 0); if (vertical) { policy = policy.vert; shrinkWrapDock = shrinkWrapDock & 1; } else { policy = policy.horz; shrinkWrapDock = shrinkWrapDock & 2; } if (shrinkWrapDock) { if (!ownerSizeModel) { ownerSizeModel = me.owner.getSizeModel(); } if (ownerSizeModel[vertical ? 'height' : 'width'].shrinkWrap) { return policy.shrinkWrap; } } return policy.stretch; }, configureItem: function(item, pos) { this.callParent(arguments); item.addCls(this._itemCls); if (!item.ignoreBorderManagement) { item.addClsWithUI(this.getDockCls(item.dock)); } }, getDockCls: function(dock) { return 'docked-' + dock; }, afterRemove: function(item) { var dom; this.callParent(arguments); item.removeCls(this._itemCls); if (!item.ignoreBorderManagement) { item.removeClsWithUI(this.getDockCls(item.dock)); } dom = item.el.dom; if (!item.destroying && dom) { dom.parentNode.removeChild(dom); } this.childrenChanged = true; }, borderCollapseMap: {}, getBorderCollapseTable: function() { var me = this, map = me.borderCollapseMap, owner = me.owner, baseCls = owner.baseCls, ui = owner.ui, table; map = map[baseCls] || (map[baseCls] = {}); table = map[ui]; if (!table) { baseCls += '-' + ui + '-outer-border-'; map[ui] = table = [ 0, baseCls + 'l', baseCls + 'b', baseCls + 'bl', baseCls + 'r', baseCls + 'rl', baseCls + 'rb', baseCls + 'rbl', baseCls + 't', baseCls + 'tl', baseCls + 'tb', baseCls + 'tbl', baseCls + 'tr', baseCls + 'trl', baseCls + 'trb', baseCls + 'trbl' ]; } return table; } }); Ext.define('Ext.util.Memento', (function() { function captureOne(src, target, prop, prefix) { src[prefix ? prefix + prop : prop] = target[prop]; } function removeOne(src, target, prop) { delete src[prop]; } function restoreOne(src, target, prop, prefix) { var name = prefix ? prefix + prop : prop, value = src[name]; if (value || src.hasOwnProperty(name)) { restoreValue(target, prop, value); } } function restoreValue(target, prop, value) { if (Ext.isDefined(value)) { target[prop] = value; } else { delete target[prop]; } } function doMany(doOne, src, target, props, prefix) { if (src) { if (Ext.isArray(props)) { var p, pLen = props.length; for (p = 0; p < pLen; p++) { doOne(src, target, props[p], prefix); } } else { doOne(src, target, props, prefix); } } } return { data: null, target: null, constructor: function(target, props) { this.data = {}; if (target) { this.target = target; if (props) { this.capture(props); } } }, capture: function(props, target, prefix) { var me = this; doMany(captureOne, me.data || (me.data = {}), target || me.target, props, prefix); }, remove: function(props) { doMany(removeOne, this.data, null, props); }, restore: function(props, clear, target, prefix) { doMany(restoreOne, this.data, target || this.target, props, prefix); if (clear !== false) { this.remove(props); } }, restoreAll: function(clear, target) { var me = this, t = target || this.target, data = me.data, prop; clear = clear !== false; for (prop in data) { if (data.hasOwnProperty(prop)) { restoreValue(t, prop, data[prop]); if (clear) { delete data[prop]; } } } } }; }())); Ext.define('Ext.container.DockingContainer', { requires: [ 'Ext.util.MixedCollection', 'Ext.Element' ], isDockingContainer: true, defaultDockWeights: { top: { render: 1, visual: 1 }, left: { render: 3, visual: 5 }, right: { render: 5, visual: 7 }, bottom: { render: 7, visual: 3 } }, dockOrder: { top: -1, left: -1, right: 1, bottom: 1 }, horizontalDocks: 0, addDocked: function(items, pos) { var me = this, rendered = me.rendered, i = 0, dockedItems = me.dockedItems, lastIndex = dockedItems.getCount(), index, instanced, item, length; items = me.prepareItems(items); length = items.length; if (rendered) { Ext.suspendLayouts(); } if (pos === undefined) { pos = lastIndex; } else { pos = Math.min(pos, lastIndex); } for (; i < length; i++) { item = items[i]; item.dock = item.dock || 'top'; if (item.dock === 'left' || item.dock === 'right') { me.horizontalDocks++; } index = pos + i; dockedItems.insert(index, item); instanced = !!item.instancedCmp; delete item.instancedCmp; item.onAdded(me, index, instanced); delete item.initOwnerCt; if (me.onDockedAdd !== Ext.emptyFn) { me.onDockedAdd(item); } if (me.hasListeners.dockedadd) { me.fireEvent('dockedadd', me, item, index); } } if (me.rendered) { me.updateLayout(); Ext.resumeLayouts(true); } return items; }, destroyDockedItems: function() { var dockedItems = this.dockedItems, c; if (dockedItems) { while ((c = dockedItems.first())) { this.removeDocked(c, true); } } }, doRenderDockedItems: function(out, renderData, after) { var me = renderData.$comp, layout = me.componentLayout, items, tree; if (layout.getDockedItems && !renderData.$skipDockedItems) { items = layout.getDockedItems('render', !after); tree = items && layout.getItemsRenderTree(items); if (tree) { Ext.DomHelper.generateMarkup(tree, out); } } }, getDockedComponent: function(comp) { if (Ext.isObject(comp)) { comp = comp.getItemId(); } return this.dockedItems.get(comp); }, getDockedItems: function(selector, beforeBody) { var dockedItems = this.getComponentLayout().getDockedItems('render', beforeBody); if (selector && dockedItems.length) { dockedItems = Ext.ComponentQuery.query(selector, dockedItems); } return dockedItems; }, getDockingRefItems: function(deep, containerItems) { var selector = deep && '*,* *', dockedItems = this.getDockedItems(selector, true), items; dockedItems.push.apply(dockedItems, containerItems); items = this.getDockedItems(selector, false); dockedItems.push.apply(dockedItems, items); return dockedItems; }, initDockingItems: function() { var me = this, items = me.dockedItems; if (!items || !items.isMixedCollection) { me.dockedItems = new Ext.util.AbstractMixedCollection(false, me.getComponentId); if (items) { me.addDocked(items); } } }, insertDocked: function(pos, items) { this.addDocked(items, pos); }, onDockedAdd: Ext.emptyFn, onDockedRemove: Ext.emptyFn, removeDocked: function(item, autoDestroy) { var me = this, layout, hasLayout; autoDestroy = autoDestroy === true || (autoDestroy !== false && me.autoDestroy); if (!me.dockedItems.contains(item)) { return item; } if (item.dock === 'left' || item.dock === 'right') { me.horizontalDocks--; } layout = me.componentLayout; hasLayout = layout && me.rendered; if (hasLayout) { layout.onRemove(item); } me.dockedItems.remove(item); item.onRemoved(item.destroying || autoDestroy); me.onDockedRemove(item); if (autoDestroy) { item.destroy(); } else if (hasLayout) { layout.afterRemove(item); } if (me.hasListeners.dockedremove) { me.fireEvent('dockedremove', me, item); } if (!me.destroying) { me.updateLayout(); } return item; }, moveDocked: function(item, side) { var me = this; if (me.rendered) { Ext.suspendLayouts(); } me.removeDocked(item, false); item.dock = side; me.addDocked(item); if (me.rendered) { if (item.frame) { Ext.getDetachedBody().appendChild(item.el); item.updateFrame(); } Ext.resumeLayouts(true); } }, setupDockingRenderTpl: function(renderTpl) { renderTpl.renderDockedItems = this.doRenderDockedItems; } }); Ext.define('Ext.panel.Panel', { extend: 'Ext.container.Container', alias: 'widget.panel', alternateClassName: 'Ext.Panel', requires: [ 'Ext.panel.Header', 'Ext.util.MixedCollection', 'Ext.toolbar.Toolbar', 'Ext.fx.Anim', 'Ext.util.KeyMap', 'Ext.panel.DD', 'Ext.XTemplate', 'Ext.layout.component.Dock', 'Ext.util.Memento' ], mixins: { docking: 'Ext.container.DockingContainer' }, childEls: [ 'body' ], renderTpl: [ '{% this.renderDockedItems(out,values,0); %}', '
{bodyCls}', ' {baseCls}-body-{ui}', ' {parent.baseCls}-body-{parent.ui}-{.}', '{childElCls}"', ' role="{bodyRole}" role="presentation"', ' style="{bodyStyle}">', '{%this.renderContainer(out,values);%}', '
', '{% this.renderDockedItems(out,values,1); %}' ], headerPosition: 'top', iconAlign: 'left', titleAlign: 'left', titleRotation: 'default', beforeRenderConfig: { glyph: null, headerPosition: null, icon: null, iconAlign: null, iconCls: null, title: null, titleAlign: null, titleRotation: null }, animCollapse: Ext.enableFx, border: true, closable: false, closeAction: 'destroy', collapsed: false, collapsedCls: 'collapsed', collapseFirst: true, collapsible: undefined, constrain: false, constrainHeader: false, dockedItems: null, tbar: null, bbar: null, fbar: null, lbar: null, rbar: null, buttons: null, floatable: true, frame: false, frameHeader: true, hideCollapseTool: false, manageHeight: true, maskElement: 'el', minButtonWidth: 75, preventHeader: false, shrinkWrapDock: false, titleCollapse: undefined, baseCls: Ext.baseCSSPrefix + 'panel', bodyPosProps: { x: 'x', y: 'y' }, componentLayout: 'dock', contentPaddingProperty: 'bodyPadding', emptyArray: [], isPanel: true, defaultBindProperty: 'title', addBodyCls: function(cls) { var me = this, body = me.rendered ? me.body : me.getProtoBody(); body.addCls(cls); return me; }, addTool: function(tools) { if (!Ext.isArray(tools)) { tools = [ tools ]; } var me = this, header = me.header, tLen = tools.length, curTools = me.tools, t, tool; if (!header || !header.isHeader) { header = null; if (!curTools) { me.tools = curTools = []; } } for (t = 0; t < tLen; t++) { tool = tools[t]; tool.toolOwner = me; if (header) { header.addTool(tool); } else { curTools.push(tool); } } me.updateHeader(); }, addTools: Ext.emptyFn, setCollapsible: function(collapsible) { var me = this, current = me.collapsible, collapseTool = me.collapseTool; me.collapsible = collapsible; if (collapsible && !current) { me.updateCollapseTool(); collapseTool = me.collapseTool; if (collapseTool) { collapseTool.show(); } } else if (!collapsible && current) { if (collapseTool) { collapseTool.hide(); } } }, addUIClsToElement: function(cls) { var me = this, result = me.callParent(arguments); me.addBodyCls([ Ext.baseCSSPrefix + cls, me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls ]); return result; }, afterCollapse: function(animated) { var me = this, ownerLayout = me.ownerLayout; me.isCollapsingOrExpanding = 0; me.updateCollapseTool(); if (animated) { me.removeCls(Ext.baseCSSPrefix + 'animating-size'); } if (ownerLayout) { ownerLayout.afterCollapse(me, animated); } me.setHiddenDocked(); me.fireEvent('collapse', me); }, afterExpand: function(animated) { var me = this, ownerLayout = me.ownerLayout; me.isCollapsingOrExpanding = 0; me.updateCollapseTool(); if (animated) { me.removeCls(Ext.baseCSSPrefix + 'animating-size'); } if (ownerLayout) { ownerLayout.afterExpand(me, animated); } me.fireEvent('expand', me); me.fireHierarchyEvent('expand'); }, beforeDestroy: function() { var me = this; Ext.destroy(me.placeholder, me.ghostPanel, me.dd); this.destroyDockedItems(); me.callParent(); }, beforeRender: function() { var me = this, wasCollapsed; me.callParent(); me.initTools(); if (!(me.preventHeader || (me.header === false))) { me.updateHeader(); } me.afterHeaderInit = true; if (me.collapsed) { if (me.isPlaceHolderCollapse()) { if (!me.hidden) { me.setHiddenState(true); me.preventCollapseFire = true; me.placeholderCollapse(); delete me.preventCollapseFire; wasCollapsed = me.collapsed; me.collapsed = false; } } else { me.beginCollapse(); me.addClsWithUI(me.collapsedCls); } } if (wasCollapsed) { me.collapsed = wasCollapsed; } }, getMemento: function(name) { var me = this; if (name && typeof name === 'string') { name += 'Memento'; return me[name] || (me[name] = new Ext.util.Memento(me)); } }, beginCollapse: function() { var me = this, lastBox = me.lastBox, rendered = me.rendered, collapseMemento = me.getMemento('collapse'), sizeModel = me.getSizeModel(), header = me.header, reExpander; collapseMemento.capture([ 'height', 'minHeight', 'width', 'minWidth' ]); if (lastBox) { collapseMemento.capture(me.restoreDimension(), lastBox, 'last.'); } if (me.collapsedVertical()) { if (sizeModel.width.shrinkWrap) { me.width = rendered ? me.getWidth() : me.width || me.minWidth || 100; } delete me.height; me.minHeight = 0; } else if (me.collapsedHorizontal()) { if (sizeModel.height.shrinkWrap) { me.height = rendered ? me.getHeight() : me.height || me.minHeight || 100; } delete me.width; me.minWidth = 0; } if (me.ownerCt) { me.ownerCt.getLayout().beginCollapse(me); } if (!me.isPlaceHolderCollapse() && header !== false) { if (header === (reExpander = me.getReExpander())) { header.collapseImmune = true; header.getInherited().collapseImmune = true; header.addClsWithUI(me.getHeaderCollapsedClasses(header)); if (header.rendered) { header.updateFrame(); } } else if (reExpander.el) { reExpander.el.show(); reExpander.hidden = false; } } if (me.resizer) { me.resizer.disable(); } }, beginDrag: function() { if (this.floatingDescendants) { this.floatingDescendants.hide(); } }, beginExpand: function() { var me = this, lastBox = me.lastBox, collapseMemento = me.getMemento('collapse'), restoreDimension = me.restoreDimension(), header = me.header, reExpander; if (collapseMemento) { collapseMemento.restore([ 'minHeight', 'minWidth', restoreDimension ]); if (lastBox) { collapseMemento.restore(restoreDimension, true, lastBox, 'last.'); } } if (me.ownerCt) { me.ownerCt.getLayout().beginExpand(me); } if (!me.isPlaceHolderCollapse() && header !== false) { if (header === (reExpander = me.getReExpander())) { delete header.collapseImmune; delete header.getInherited().collapseImmune; header.removeClsWithUI(me.getHeaderCollapsedClasses(header)); if (header.rendered) { header.expanding = true; header.updateFrame(); delete header.expanding; } } else { reExpander.hidden = true; reExpander.el.hide(); } } if (me.resizer) { me.resizer.enable(); } }, bridgeToolbars: function() { var me = this, docked = [], minButtonWidth = me.minButtonWidth, fbar, fbarDefaults; function initToolbar(toolbar, pos, useButtonAlign) { if (Ext.isArray(toolbar)) { toolbar = { xtype: 'toolbar', items: toolbar }; } else if (!toolbar.xtype) { toolbar.xtype = 'toolbar'; } toolbar.dock = pos; if (useButtonAlign) { toolbar.layout = Ext.applyIf(toolbar.layout || {}, { pack: { left: 'start', center: 'center' }[me.buttonAlign] || 'end' }); } return toolbar; } if (me.tbar) { docked.push(initToolbar(me.tbar, 'top')); me.tbar = null; } if (me.bbar) { docked.push(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', true); fbar.ui = 'footer'; if (minButtonWidth) { fbarDefaults = fbar.defaults; fbar.defaults = function(config) { var defaults = fbarDefaults || {}, isButton = !config.xtype || config.isButton, cls; if (!isButton) { cls = Ext.ClassManager.getByAlias('widget.' + config.xtype); if (cls) { isButton = cls.prototype.isButton; } } if (isButton && !('minWidth' in defaults)) { defaults = Ext.apply({ minWidth: minButtonWidth }, defaults); } return defaults; }; } docked.push(fbar); me.fbar = null; } if (me.lbar) { docked.push(initToolbar(me.lbar, 'left')); me.lbar = null; } if (me.rbar) { docked.push(initToolbar(me.rbar, 'right')); me.rbar = null; } if (me.dockedItems) { if (me.dockedItems.isMixedCollection) { me.addDocked(docked); } else { if (!Ext.isArray(me.dockedItems)) { me.dockedItems = [ me.dockedItems ]; } me.dockedItems = me.dockedItems.concat(docked); } } else { me.dockedItems = docked; } }, close: function() { if (this.fireEvent('beforeclose', this) !== false) { this.doClose(); } }, collapse: function(direction, animate) { var me = this, collapseDir = direction || me.collapseDirection, ownerCt = me.ownerCt, layout = me.ownerLayout, rendered = me.rendered; if (me.isCollapsingOrExpanding) { return me; } if (arguments.length < 2) { animate = me.animCollapse; } if (me.collapsed || me.fireEvent('beforecollapse', me, direction, animate) === false) { return me; } if (layout && layout.onBeforeComponentCollapse) { if (layout.onBeforeComponentCollapse(me) === false) { return me; } } if (rendered && ownerCt && me.isPlaceHolderCollapse()) { return me.placeholderCollapse(direction, animate); } me.collapsed = collapseDir; if (rendered) { me.beginCollapse(); } me.getInherited().collapsed = true; me.fireHierarchyEvent('collapse'); if (rendered) { me.doCollapseExpand(1, animate); } return me; }, collapsedHorizontal: function() { var dir = this.getCollapsed(); return dir === 'left' || dir === 'right'; }, collapsedVertical: function() { var dir = this.getCollapsed(); return dir === 'top' || dir === 'bottom'; }, convertCollapseDir: function(collapseDir) { return collapseDir.substr(0, 1); }, createGhost: function(cls) { var me = this, header = me.header, frame = me.frame && !me.alwaysFramed; return { xtype: 'panel', hidden: false, header: header ? { titleAlign: header.getTitleAlign() } : null, ui: frame ? me.ui.replace(/-framed$/, '') : me.ui, id: me.id + '-ghost', renderTo: Ext.getBody(), resizable: false, draggable: false, closable: false, floating: true, shadow: false, frame: frame, shim: me.shim, alwaysFramed: me.alwaysFramed, overlapHeader: me.overlapHeader, headerPosition: me.getHeaderPosition(), titleRotation: me.getTitleRotation(), baseCls: me.baseCls, getRefOwner: function() { return me.getRefOwner(); }, cls: me.baseCls + '-ghost ' + (cls || '') }; }, createReExpander: function(direction, defaults) { var me = this, isLeft = direction === 'left', isRight = direction === 'right', isVertical = isLeft || isRight, ownerCt = me.ownerCt, result = Ext.apply({ hideMode: 'offsets', title: me.getTitle(), titleAlign: me.getTitleAlign(), vertical: isVertical, textCls: me.headerTextCls, icon: me.getIcon(), iconCls: me.getIconCls(), iconAlign: me.getIconAlign(), glyph: me.getGlyph(), baseCls: me.self.prototype.baseCls + '-header', ui: me.ui, frame: me.frame && me.frameHeader, ignoreParentFrame: me.frame || me.overlapHeader, ignoreBorderManagement: me.frame || me.ignoreHeaderBorderManagement, indicateDrag: me.draggable, collapseImmune: true, headerRole: me.headerRole, ownerCt: (ownerCt && me.collapseMode === 'placeholder') ? ownerCt : me, ownerLayout: me.componentLayout, forceOrientation: true, margin: me.margin }, defaults); if (me.collapseMode === 'mini') { if (isVertical) { result.width = 1; } else { result.height = 1; } } if (!me.hideCollapseTool) { if (isLeft || (isRight && me.isPlaceHolderCollapse())) { result.titlePosition = 1; } result.tools = [ { xtype: 'tool', type: 'expand-' + me.getOppositeDirection(direction), uiCls: [ 'top' ], handler: me.toggleCollapse, scope: me } ]; } result = new Ext.panel.Header(result); result.addClsWithUI(me.getHeaderCollapsedClasses(result)); return result; }, doClose: function() { this.fireEvent('close', this); this[this.closeAction](); }, doCollapseExpand: function(flags, animate) { var me = this, originalAnimCollapse = me.animCollapse, ownerLayout = me.ownerLayout; me.animCollapse = animate; me.isCollapsingOrExpanding = flags; if (animate) { me.addCls(Ext.baseCSSPrefix + 'animating-size'); } if (ownerLayout && !animate) { ownerLayout.onContentChange(me); } else { me.updateLayout({ isRoot: true }); } me.animCollapse = originalAnimCollapse; return me; }, endDrag: function() { if (this.floatingDescendants) { this.floatingDescendants.show(); } }, expand: function(animate) { var me = this, layout = me.ownerLayout, rendered = me.rendered; if (me.isCollapsingOrExpanding) { return me; } if (!arguments.length) { animate = me.animCollapse; } if (!me.collapsed && !me.floatedFromCollapse) { return me; } if (me.fireEvent('beforeexpand', me, animate) === false) { return me; } if (layout && layout.onBeforeComponentExpand) { if (layout.onBeforeComponentExpand(me) === false) { return me; } } delete me.getInherited().collapsed; if (rendered && me.isPlaceHolderCollapse()) { return me.placeholderExpand(animate); } me.restoreHiddenDocked(); if (rendered) { me.beginExpand(); } me.collapsed = false; if (me.rendered) { me.doCollapseExpand(2, animate); } return me; }, findReExpander: function(direction) { var me = this, c = Ext.Component, dockedItems = me.dockedItems.items, dockedItemCount = dockedItems.length, comp, i; if (me.collapseMode === 'mini') { return; } switch (direction) { case c.DIRECTION_TOP: case c.DIRECTION_BOTTOM: for (i = 0; i < dockedItemCount; i++) { comp = dockedItems[i]; if (!comp.hidden) { if (comp.isHeader && (!comp.dock || comp.dock === 'top' || comp.dock === 'bottom')) { return comp; } } }; break; case c.DIRECTION_LEFT: case c.DIRECTION_RIGHT: for (i = 0; i < dockedItemCount; i++) { comp = dockedItems[i]; if (!comp.hidden) { if (comp.isHeader && (comp.dock === 'left' || comp.dock === 'right')) { return comp; } } }; break; default: throw ('Panel#findReExpander must be passed a valid collapseDirection'); } }, floatCollapsedPanel: function() { var me = this, placeholder = me.placeholder, ps = placeholder.getSize(), floatCls = Ext.baseCSSPrefix + 'border-region-slide-in', collapsed = me.collapsed, layoutOwner = me.ownerCt || me, slideDirection, onBodyMousedown, myBox; if (me.isSliding) { return; } if (me.el.hasCls(floatCls)) { me.slideOutFloatedPanel(); return; } me.isSliding = true; placeholder.el.hide(); placeholder.hidden = true; me.el.show(); me.setHiddenState(false); me.collapsed = false; layoutOwner.updateLayout(); placeholder.el.show(); placeholder.hidden = false; me.el.hide(); me.setHiddenState(true); me.collapsed = collapsed; layoutOwner.updateLayout(); myBox = me.getBox(false, true); me.slideOutTask = me.slideOutTask || new Ext.util.DelayedTask(me.slideOutFloatedPanel, me); if (Ext.supports.Touch) { Ext.on('mousedown', onBodyMousedown = function(event) { if (!event.within(me.el)) { Ext.un('mousedown', onBodyMousedown); me.slideOutFloatedPanel(); } }); } if (!me.placeholderListener) { me.placeholderListener = placeholder.on({ resize: me.onPlaceholderResize, scope: me, destroyable: true }); } placeholder.el.on('mouseleave', me.onMouseLeaveFloated, me); me.el.on('mouseleave', me.onMouseLeaveFloated, me); placeholder.el.on('mouseenter', me.onMouseEnterFloated, me); me.el.on('mouseenter', me.onMouseEnterFloated, me); me.el.addCls(floatCls); me.floated = collapsed; if (me.collapseTool) { me.collapseTool.el.hide(); } switch (me.collapsed) { case 'top': me.width = ps.width; me.setLocalXY(myBox.x, myBox.y + ps.height); break; case 'right': me.height = ps.height; me.setLocalXY(myBox.x - ps.width, myBox.y); break; case 'bottom': me.width = ps.width; me.setLocalXY(myBox.x, myBox.y - ps.height); break; case 'left': me.height = ps.height; me.setLocalXY(myBox.x + ps.width, myBox.y); break; } slideDirection = me.convertCollapseDir(me.collapsed); me.floatedFromCollapse = me.collapsed; me.collapsed = false; me.setHiddenState(false); me.el.slideIn(slideDirection, { preserveScroll: true, duration: Ext.Number.from(me.animCollapse, Ext.fx.Anim.prototype.duration), listeners: { afteranimate: function() { me.isSliding = false; me.fireEvent('float', me); } } }); }, onPlaceholderResize: function(ph, newWidth, newHeight) { var me = this, myBox = me.getBox(false, true), phBox = ph.getBox(false, true); switch (me.floated) { case 'top': me.width = newWidth; me.setLocalY(phBox.y + phBox.height); break; case 'right': me.height = newHeight; me.setLocalX(phBox.x - myBox.width); break; case 'bottom': me.width = newWidth; me.setLocalY(phBox.y - myBox.height); break; case 'left': me.height = newHeight; me.setLocalX(phBox.x + phBox.width); break; } me.updateLayout({ isRoot: true }); }, getAnimationProps: function() { var me = this, animCollapse = me.animCollapse, props; props = me.callParent(); if (typeof animCollapse === 'number') { props.duration = animCollapse; } return props; }, getCollapsed: function() { var me = this; if (me.collapsed === true) { return me.collapseDirection; } return me.collapsed; }, getCollapsedDockedItems: function() { var me = this; return me.header === false || me.collapseMode === 'placeholder' ? me.emptyArray : [ me.getReExpander() ]; }, getComponent: function(comp) { var component = this.callParent(arguments); if (component === undefined && !Ext.isNumber(comp)) { component = this.getDockedComponent(comp); } return component; }, getHeader: function() { return this.header; }, getHeaderCollapsedClasses: function(header) { var me = this, collapsedCls = me.collapsedCls, collapsedClasses; collapsedClasses = [ collapsedCls, collapsedCls + '-' + header.getDockName() ]; if (me.border && (!me.frame || (me.frame && Ext.supports.CSS3BorderRadius))) { collapsedClasses.push(collapsedCls + '-border-' + header.getDockName()); } return collapsedClasses; }, getKeyMap: function() { return this.keyMap || (this.keyMap = new Ext.util.KeyMap(Ext.apply({ target: this.el }, this.keys))); }, 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; } }, getPlaceholder: function(direction) { var me = this, collapseDir = direction || me.collapseDirection, listeners = null, placeholder = me.placeholder, floatable = me.floatable, titleCollapse = me.titleCollapse; if (!placeholder) { if (floatable || (me.collapsible && titleCollapse)) { listeners = { click: { fn: (!titleCollapse && floatable) ? me.floatCollapsedPanel : me.toggleCollapse, element: 'el', scope: me } }; } me.placeholder = placeholder = Ext.widget(me.createReExpander(collapseDir, { id: me.id + '-placeholder', listeners: listeners })); } if (!placeholder.placeholderFor) { if (!placeholder.isComponent) { me.placeholder = placeholder = me.lookupComponent(placeholder); } Ext.applyIf(placeholder, { margin: me.margin, placeholderFor: me, synthetic: true }); placeholder.addCls([ Ext.baseCSSPrefix + 'region-collapsed-placeholder', Ext.baseCSSPrefix + 'region-collapsed-' + collapseDir + '-placeholder', me.collapsedCls ]); } return placeholder; }, getProtoBody: function() { var me = this, body = me.protoBody; if (!body) { me.protoBody = body = new Ext.util.ProtoElement({ cls: me.bodyCls, style: me.bodyStyle, clsProp: 'bodyCls', styleProp: 'bodyStyle', styleIsText: true }); } return body; }, getReExpander: function(direction) { var me = this, collapseDir = direction || me.collapseDirection, reExpander = me.reExpander || me.findReExpander(collapseDir); me.expandDirection = me.getOppositeDirection(collapseDir); if (!reExpander) { me.reExpander = reExpander = me.createReExpander(collapseDir, { dock: collapseDir, cls: Ext.baseCSSPrefix + 'docked ' + me.baseCls + '-' + me.ui + '-collapsed', isCollapsedExpander: true }); me.dockedItems.insert(0, reExpander); } return reExpander; }, getRefItems: function(deep) { var items = this.callParent(arguments); return this.getDockingRefItems(deep, items); }, getState: function() { var me = this, state = me.callParent() || {}, collapsed = me.collapsed, floated = me.floated, memento; if (floated) { me.collapsed = floated; } state = me.addPropertyToState(state, 'collapsed'); if (floated) { me.collapsed = collapsed; } if (me.getCollapsed()) { memento = me.getMemento('collapse').data; state = me.addPropertyToState(state, 'collapsed', memento); if (me.collapsedVertical()) { delete state.height; if (memento) { state = me.addPropertyToState(state, 'height', memento.height); } } else { delete state.width; if (memento) { state = me.addPropertyToState(state, 'width', memento.width); } } } return state; }, applyState: function(state) { var me = this, collapseMemento = {}, collapsed; if (state) { collapsed = state.collapsed; if (collapsed) { collapseMemento = me.getMemento('collapse'); Ext.Object.merge(collapseMemento.data, collapsed); state.collapsed = true; } me.callParent(arguments); } }, ghost: function(cls) { var me = this, ghostPanel = me.ghostPanel, box = me.getBox(), header = me.header, ghostHeader, tools, icon, iconCls, glyph, i; if (!ghostPanel) { me.ghostPanel = ghostPanel = Ext.widget(me.createGhost(cls)); ghostPanel.el.dom.removeAttribute('tabIndex'); } else { ghostPanel.el.show(); } ghostPanel.setHiddenState(false); ghostPanel.floatParent = me.floatParent; ghostPanel.toFront(); if (header && !me.preventHeader) { ghostHeader = ghostPanel.header; ghostHeader.suspendLayouts(); tools = ghostHeader.query('tool'); for (i = tools.length; i--; ) { ghostHeader.remove(tools[i]); } ghostHeader.setTitlePosition(0); ghostPanel.addTool(me.ghostTools()); ghostPanel.setTitle(me.getTitle()); ghostHeader.setTitlePosition(header.titlePosition); iconCls = me.getIconCls(); if (iconCls) { ghostPanel.setIconCls(iconCls); } else { icon = me.getIcon(); if (icon) { ghostPanel.setIcon(icon); } else { glyph = me.getGlyph(); if (glyph) { ghostPanel.setGlyph(glyph); } } } ghostHeader.addCls(Ext.baseCSSPrefix + 'header-ghost'); ghostHeader.resumeLayouts(); } ghostPanel.setPagePosition(box.x, box.y); ghostPanel.setSize(box.width, box.height); me.el.hide(); return ghostPanel; }, ghostTools: function() { var tools = [], header = this.header, headerTools = header ? header.query('tool[hidden=false]') : [], t, tLen, tool; if (headerTools.length) { t = 0; tLen = headerTools.length; for (; t < tLen; t++) { tool = headerTools[t]; tools.push({ type: tool.type }); } } else { tools = [ { type: 'placeholder' } ]; } return tools; }, initBodyBorder: function() { var me = this; if (me.frame && me.bodyBorder) { if (!Ext.isNumber(me.bodyBorder)) { me.bodyBorder = 1; } me.getProtoBody().setStyle('border-width', this.unitizeBox(me.bodyBorder)); } }, initBodyStyles: function() { var me = this, body = me.getProtoBody(); if (me.bodyPadding !== undefined) { if (me.layout.managePadding) { body.setStyle('padding', 0); } else { body.setStyle('padding', this.unitizeBox((me.bodyPadding === true) ? 5 : me.bodyPadding)); } } me.initBodyBorder(); }, initBorderProps: function() { var me = this; 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; } }, initComponent: function() { var me = this; if (me.collapsible) { me.addStateEvents([ 'expand', 'collapse' ]); } if (me.unstyled) { me.setUI('plain'); } if (me.frame) { me.setUI(me.ui + '-framed'); } me.bridgeToolbars(); me.initBorderProps(); me.callParent(); me.collapseDirection = me.collapseDirection || me.getHeaderPosition() || Ext.Component.DIRECTION_TOP; me.hiddenOnCollapse = new Ext.dom.CompositeElement(); }, initItems: function() { this.callParent(); this.initDockingItems(); }, initRenderData: function() { var me = this, data = me.callParent(); me.initBodyStyles(); me.protoBody.writeTo(data); delete me.protoBody; return data; }, calculateConstrainedPosition: function(constrainTo, proposedPosition, local, proposedSize) { var me = this, header = me.header, lastBox, fp; if (me.constrainHeader) { lastBox = header.lastBox; if (proposedSize) { if (!header.vertical) { proposedSize = [ proposedSize[0], lastBox ? lastBox.height : proposedSize[1] ]; } else { proposedSize = [ lastBox ? lastBox.width : proposedSize[0], proposedSize[1] ]; } } else if (lastBox) { proposedSize = [ lastBox.width, lastBox.height ]; } fp = me.floatParent; constrainTo = constrainTo || me.constrainTo || (fp ? fp.getTargetEl() : null) || me.container || me.el.parent(); } return me.callParent([ constrainTo, proposedPosition, local, proposedSize ]); }, initTools: function() { var me = this, tools = me.tools, i, tool; me.tools = []; for (i = tools && tools.length; i; ) { --i; me.tools[i] = tool = tools[i]; tool.toolOwner = me; } if (me.collapsible && !(me.hideCollapseTool || me.header === false || me.preventHeader)) { me.updateCollapseTool(); if (me.collapseFirst) { me.tools.unshift(me.collapseTool); } } me.addTools(); if (me.pinnable) { me.initPinnable(); } if (me.closable) { me.addClsWithUI('closable'); me.addTool({ xtype: 'tool', type: 'close', scope: me, handler: me.close }); } if (me.collapseTool && !me.collapseFirst) { me.addTool(me.collapseTool); } }, isLayoutRoot: function() { if (this.floatedFromCollapse) { return true; } return this.callParent(); }, isPlaceHolderCollapse: function() { return this.collapseMode === 'placeholder'; }, isVisible: function(deep) { var me = this; if (me.collapsed && me.placeholder) { return me.placeholder.isVisible(deep); } return me.callParent(arguments); }, onBoxReady: function() { this.callParent(arguments); if (this.collapsed) { this.setHiddenDocked(); } }, onHide: function(animateTarget, cb, scope) { var me = this, dd = me.dd; if (me.floatedFromCollapse) { me.slideOutFloatedPanel(true); } if (me.draggable && dd) { dd.endDrag(); } if (me.collapsed && me.placeholder) { if (me.splitter) { Ext.suspendLayouts(); me.splitter.hide(); Ext.resumeLayouts(); } me.placeholder.hide(); } else { me.callParent([ animateTarget, cb, scope ]); } }, onMouseEnterFloated: function(e) { this.slideOutTask.cancel(); }, onMouseLeaveFloated: function(e) { this.slideOutTask.delay(500); }, onRemoved: function(destroying) { var me = this; if (me.placeholder && !destroying) { me.ownerCt.remove(me.placeholder, false); } me.callParent(arguments); }, onShow: function() { var me = this; if (me.collapsed && me.isPlaceHolderCollapse()) { if (me.splitter) { Ext.suspendLayouts(); me.splitter.show(); Ext.resumeLayouts(); } me.setHiddenState(true); me.placeholderCollapse(); } else { me.callParent(arguments); } }, placeholderCollapse: function(direction, animate) { var me = this, ownerCt = me.ownerCt, collapseDir = direction || me.collapseDirection, floatCls = Ext.baseCSSPrefix + 'border-region-slide-in', placeholder = me.getPlaceholder(collapseDir), slideInDirection; me.isCollapsingOrExpanding = 1; me.setHiddenState(true); me.collapsed = collapseDir; if (placeholder.rendered) { if (placeholder.el.dom.parentNode !== me.el.dom.parentNode) { me.el.dom.parentNode.insertBefore(placeholder.el.dom, me.el.dom); } placeholder.hidden = false; placeholder.setHiddenState(false); placeholder.el.show(); ownerCt.updateLayout(); } else { ownerCt.insert(ownerCt.items.indexOf(me), placeholder); } if (me.rendered) { me.el.setVisibilityMode(me.placeholderCollapseHideMode); if (animate) { me.el.addCls(floatCls); placeholder.el.hide(); slideInDirection = me.convertCollapseDir(collapseDir); me.el.slideOut(slideInDirection, { preserveScroll: true, duration: Ext.Number.from(animate, Ext.fx.Anim.prototype.duration), listeners: { afteranimate: function() { me.el.removeCls(floatCls); placeholder.el.show().setStyle('display', 'none').slideIn(slideInDirection, { easing: 'linear', duration: 100, listeners: { afteranimate: function() { placeholder.focus(); placeholder.setHiddenState(false); me.isCollapsingOrExpanding = 0; me.fireEvent('collapse', me); } } }); } } }); } else { me.el.hide(); placeholder.setHiddenState(false); me.isCollapsingOrExpanding = 0; me.fireEvent('collapse', me); } } else { me.isCollapsingOrExpanding = 0; if (!me.preventCollapseFire) { me.fireEvent('collapse', me); } } return me; }, placeholderExpand: function(animate) { var me = this, collapseDir = me.collapsed, floatCls = Ext.baseCSSPrefix + 'border-region-slide-in', finalPos, floatedPos, center = me.ownerLayout ? me.ownerLayout.centerRegion : null; if (Ext.Component.layoutSuspendCount) { animate = false; } if (me.floatedFromCollapse) { floatedPos = me.getPosition(true); me.slideOutFloatedPanelBegin(); me.slideOutFloatedPanelEnd(); me.floated = false; } if (animate) { Ext.suspendLayouts(); me.placeholder.hide(); me.el.show(); me.collapsed = false; me.setHiddenState(false); if (center && !floatedPos) { center.hidden = true; } Ext.resumeLayouts(true); center.hidden = false; me.el.addCls(floatCls); me.isCollapsingOrExpanding = 2; if (floatedPos) { finalPos = me.getXY(); me.setLocalXY(floatedPos[0], floatedPos[1]); me.setXY([ finalPos[0], finalPos[1] ], { duration: Ext.Number.from(animate, Ext.fx.Anim.prototype.duration), listeners: { afteranimate: function() { me.el.removeCls(floatCls); me.isCollapsingOrExpanding = 0; me.fireEvent('expand', me); } } }); } else { me.el.hide(); me.placeholder.el.show(); me.placeholder.hidden = false; me.setHiddenState(false); me.el.slideIn(me.convertCollapseDir(collapseDir), { preserveScroll: true, duration: Ext.Number.from(animate, Ext.fx.Anim.prototype.duration), listeners: { afteranimate: function() { me.el.removeCls(floatCls); me.placeholder.hide(); me.updateLayout(); me.isCollapsingOrExpanding = 0; me.fireEvent('expand', me); } } }); } } else { me.floated = me.collapsed = false; me.el.removeCls(floatCls); Ext.suspendLayouts(); me.placeholder.hide(); me.show(); Ext.resumeLayouts(true); me.fireEvent('expand', me); } return me; }, remove: function(component, autoDestroy) { if (this.dockedItems.contains(component)) { this.removeDocked(component, autoDestroy); } else { this.callParent([ component, autoDestroy ]); } return component; }, removeBodyCls: function(cls) { var me = this, body = me.rendered ? me.body : me.getProtoBody(); body.removeCls(cls); return me; }, removeUIClsFromElement: function(cls) { var me = this, result = me.callParent(arguments); me.removeBodyCls([ Ext.baseCSSPrefix + cls, me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls ]); return result; }, restoreDimension: function() { var dir = this.collapseDirection; return (dir === 'top' || dir === 'bottom') ? 'height' : 'width'; }, restoreHiddenDocked: function() { var toShow = this.hiddenOnCollapse; toShow.setStyle('visibility', ''); toShow.clear(); }, setBodyStyle: function(style, value) { var me = this, body = me.rendered ? me.body : me.getProtoBody(); if (Ext.isFunction(style)) { style = style(); } if (arguments.length === 1) { if (Ext.isString(style)) { style = Ext.Element.parseStyles(style); } body.setStyle(style); } else { body.setStyle(style, value); } return me; }, setBorder: function(border, targetEl) { if (targetEl) { return; } var me = this, header = me.header; if (!border) { border = 0; } else if (border === true) { border = '1px'; } else { border = me.unitizeBox(border); } if (header) { if (header.isHeader) { header.setBorder(border); } else { header.border = border; } } if (me.rendered && me.bodyBorder !== false) { me.body.setStyle('border-width', border); } me.updateLayout(); me.border = border; }, setCollapsed: function(collapsed) { this[collapsed ? 'collapse' : 'expand'](); }, setGlyph: function(glyph) { var me = this, oldGlyph = me.glyph, header = me.header, placeholder = me.placeholder; if (glyph !== oldGlyph) { me.glyph = glyph; if (header) { if (header.isHeader) { header.setGlyph(glyph); } else { header.glyph = glyph; } } else if (me.rendered || me.afterHeaderInit) { me.updateHeader(); } if (placeholder && placeholder.setGlyph) { placeholder.setGlyph(glyph); } me.fireEvent('glyphchange', me, glyph, oldGlyph); } }, setIcon: function(icon) { var me = this, oldIcon = me.icon, header = me.header, placeholder = me.placeholder; if (icon !== oldIcon) { me.icon = icon; if (header) { if (header.isHeader) { header.setIcon(icon); } else { header.icon = icon; } } else if (me.rendered || me.afterHeaderInit) { me.updateHeader(); } if (placeholder && placeholder.setIcon) { placeholder.setIcon(icon); } me.fireEvent('iconchange', me, icon, oldIcon); } }, setIconCls: function(iconCls) { var me = this, oldIconCls = me.iconCls, header = me.header, placeholder = me.placeholder; if (iconCls !== oldIconCls) { me.iconCls = iconCls; if (header) { if (header.isHeader) { header.setIconCls(iconCls); } else { header.iconCls = iconCls; } } else if (me.rendered || me.afterHeaderInit) { me.updateHeader(); } if (placeholder && placeholder.setIconCls) { placeholder.setIconCls(iconCls); } me.fireEvent('iconclschange', me, iconCls, oldIconCls); } }, setTitle: function(title) { var me = this, oldTitle = me.title, header = me.header, reExpander = me.reExpander, placeholder = me.placeholder; if (title !== oldTitle) { me.title = title; if (header) { if (header.isHeader) { header.setTitle(title); } } else if (me.rendered || me.afterHeaderInit) { me.updateHeader(); } if (reExpander) { reExpander.setTitle(title); } if (placeholder && placeholder.setTitle) { placeholder.setTitle(title); } me.fireEvent('titlechange', me, title, oldTitle); } }, setHiddenDocked: function() { var me = this, toHide = me.hiddenOnCollapse, items = me.getDockedItems(), len = items.length, i = 0, item, reExpander; if (me.header !== false) { reExpander = me.getReExpander(); } toHide.add(me.body); for (; i < len; i++) { item = items[i]; if (item && item !== reExpander && item.el) { toHide.add(item.el); } } toHide.setStyle('visibility', 'hidden'); }, setUI: function(ui) { var me = this; me.callParent(arguments); if (me.header && me.header.rendered) { me.header.setUI(ui); } }, toggleCollapse: function() { return (this.collapsed || this.floatedFromCollapse) ? this.expand() : this.collapse(); }, updateCollapseTool: function() { var me = this, collapseTool = me.collapseTool; if (!collapseTool && me.collapsible) { me.collapseDirection = me.collapseDirection || me.getHeaderPosition() || 'top'; me.collapseTool = me.expandTool = collapseTool = Ext.widget({ xtype: 'tool', handler: me.toggleCollapse, scope: me }); } if (collapseTool) { if (me.collapsed && !me.isPlaceHolderCollapse()) { collapseTool.setType('expand-' + me.getOppositeDirection(me.collapseDirection)); } else { collapseTool.setType('collapse-' + me.collapseDirection); } } }, updateHeaderPosition: function(position) { var header = this.header; if (header && header.isHeader) { header.setDock(position); } }, updateIconAlign: function(align) { var header = this.header; if (header && header.isHeader) { header.setIconAlign(align); } }, updateTitleAlign: function(align) { var header = this.header; if (header && header.isHeader) { header.setTitleAlign(align); } }, updateTitleRotation: function(rotation) { var header = this.header; if (header && header.isHeader) { header.setTitleRotation(rotation); } }, unghost: function(show, matchPosition, focus) { var me = this, ghostPanel = me.ghostPanel; if (!ghostPanel) { return; } if (show !== false) { me.el.show(); if (matchPosition !== false) { me.setPagePosition(ghostPanel.getXY()); if (me.hideMode === 'offsets') { delete me.el.hideModeStyles; } } if (focus) { me.focus(false, 10); } } ghostPanel.el.hide(); ghostPanel.setHiddenState(true); }, updateHeader: function(force) { var me = this, header = me.header, title = me.getTitle(), tools = me.tools, icon = me.getIcon(), glyph = me.getGlyph(), iconCls = me.getIconCls(), hasIcon = glyph || icon || iconCls, headerPosition = me.getHeaderPosition(), vertical = headerPosition === 'left' || headerPosition === 'right'; if (Ext.isObject(header) || (header !== false && (force || (title || hasIcon) || (tools && tools.length) || (me.collapsible && !me.titleCollapse)))) { if (header && header.isHeader) { header.show(); } else { header = me.header = Ext.widget(Ext.merge({ xtype: 'header', title: title, titleAlign: me.getTitleAlign(), vertical: vertical, dock: me.getHeaderPosition() || 'top', titleRotation: me.getTitleRotation(), textCls: me.headerTextCls, iconCls: iconCls, iconAlign: me.getIconAlign(), icon: icon, glyph: glyph, baseCls: me.baseCls + '-header', tools: tools, ui: me.ui, id: me.id + '_header', overCls: me.headerOverCls, indicateDrag: me.draggable, frame: (me.frame || me.alwaysFramed) && me.frameHeader, ignoreParentFrame: me.frame || me.overlapHeader, ignoreBorderManagement: me.frame || me.ignoreHeaderBorderManagement, headerRole: me.headerRole, ownerCt: me, synthetic: true, listeners: me.collapsible && me.titleCollapse ? { click: me.toggleCollapse, scope: me } : null }, me.header)); me.addDocked(header, 0); } } else if (header) { header.hide(); } }, privates: { addUIToElement: function() { var me = this; me.callParent(arguments); me.addBodyCls(me.baseCls + '-body-' + me.ui); }, applyTargetCls: function(targetCls) { this.getProtoBody().addCls(targetCls); }, getDefaultContentTarget: function() { return this.body; }, getTargetEl: function() { var me = this; return me.body || me.protoBody || me.frameBody || me.el; }, initDraggable: function() { var me = this; if (me.simpleDrag) { me.initSimpleDraggable(); } else { me.dd = new Ext.panel.DD(me, Ext.isBoolean(me.draggable) ? null : me.draggable); } }, initResizable: function() { this.callParent(arguments); if (this.collapsed) { this.resizer.disable(); } }, initSimpleDraggable: function() { var me = this, ddConfig, dd; if (!me.header) { me.updateHeader(true); } if (me.header) { 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; } dd = me.dd = new Ext.util.ComponentDragger(me, ddConfig); me.relayEvents(dd, [ 'dragstart', 'drag', 'dragend' ]); if (me.maximized) { dd.disable(); } } }, removeUIFromElement: function() { var me = this; me.callParent(arguments); me.removeBodyCls(me.baseCls + '-body-' + me.ui); }, setupRenderTpl: function(renderTpl) { this.callParent(arguments); this.setupDockingRenderTpl(renderTpl); }, slideOutFloatedPanel: function(preventAnimate) { var me = this, compEl = me.el, collapseDirection, afterSlideOut = function() { me.slideOutFloatedPanelEnd(); me.el.removeCls(Ext.baseCSSPrefix + 'border-region-slide-in'); }; if (me.isSliding || me.isDestroyed) { return; } me.isSliding = true; me.floated = false; me.slideOutFloatedPanelBegin(); if (preventAnimate) { compEl.hide(); return afterSlideOut(); } if (typeof me.collapsed === 'string') { collapseDirection = me.convertCollapseDir(me.collapsed); } compEl.slideOut(collapseDirection, { preserveScroll: true, duration: Ext.Number.from(me.animCollapse, Ext.fx.Anim.prototype.duration), listeners: { afteranimate: afterSlideOut } }); }, slideOutFloatedPanelBegin: function() { var me = this, placeholderEl = me.placeholder.el, el = me.el; me.collapsed = me.floatedFromCollapse; me.setHiddenState(true); me.floatedFromCollapse = null; placeholderEl.un('mouseleave', me.onMouseLeaveFloated, me); el.un('mouseleave', me.onMouseLeaveFloated, me); placeholderEl.un('mouseenter', me.onMouseEnterFloated, me); el.un('mouseenter', me.onMouseEnterFloated, me); }, slideOutFloatedPanelEnd: function(suppressEvents) { var me = this; if (me.collapseTool) { me.collapseTool.el.show(); } me.slideOutTask.cancel(); me.isSliding = false; if (!suppressEvents) { me.fireEvent('unfloat', me); } } } }, function() { var proto = this.prototype; proto.animCollapse = Ext.enableFx; proto.placeholderCollapseHideMode = Ext.Element.VISIBILITY; }); Ext.define("Ext.form.Labelable", { extend: 'Ext.Mixin', requires: [ 'Ext.XTemplate', 'Ext.overrides.dom.Element' ], isLabelable: true, mixinConfig: { id: 'labelable', on: { beforeRender: 'beforeLabelRender', onRender: 'onLabelRender' } }, config: { childEls: [ 'labelEl', 'bodyEl', 'errorEl', 'errorWrapEl' ] }, labelableRenderTpl: [ '{beforeLabelTpl}', '', '{afterLabelTpl}', '
', ' {fieldBodyCls} {fieldBodyCls}-{ui} {growCls} {extraFieldBodyCls}"', ' style="{bodyStyle}">', '{beforeBodyEl}', '{beforeSubTpl}', '{[values.$comp.getSubTplMarkup(values)]}', '{afterSubTpl}', '{afterBodyEl}', '
', '', '
', '', '
', '
', { disableFormats: true } ], activeErrorsTpl: undefined, htmlActiveErrorsTpl: [ '', '
    ', '', '
    {fieldLabel}
    ', '
    ', '
  • {.}
  • ', '
', '
' ], plaintextActiveErrorsTpl: [ '', '', '{fieldLabel}\n', '', '\n{.}', '' ], isFieldLabelable: true, formItemCls: Ext.baseCSSPrefix + 'form-item', labelCls: Ext.baseCSSPrefix + 'form-item-label', topLabelCls: Ext.baseCSSPrefix + 'form-item-label-top', rightLabelCls: Ext.baseCSSPrefix + 'form-item-label-right', labelInnerCls: Ext.baseCSSPrefix + 'form-item-label-inner', topLabelSideErrorCls: Ext.baseCSSPrefix + 'form-item-label-top-side-error', errorMsgCls: Ext.baseCSSPrefix + 'form-error-msg', errorWrapCls: Ext.baseCSSPrefix + 'form-error-wrap', errorWrapSideCls: Ext.baseCSSPrefix + 'form-error-wrap-side', errorWrapUnderCls: Ext.baseCSSPrefix + 'form-error-wrap-under', errorWrapUnderSideLabelCls: Ext.baseCSSPrefix + 'form-error-wrap-under-side-label', baseBodyCls: Ext.baseCSSPrefix + 'form-item-body', invalidIconCls: Ext.baseCSSPrefix + 'form-invalid-icon', invalidUnderCls: Ext.baseCSSPrefix + 'form-invalid-under', noLabelCls: Ext.baseCSSPrefix + 'form-item-no-label', fieldBodyCls: '', invalidCls: Ext.baseCSSPrefix + 'form-invalid', fieldLabel: undefined, labelAlign: 'left', labelWidth: 100, labelPad: 5, labelSeparator: ':', hideLabel: false, hideEmptyLabel: true, preventMark: false, autoFitErrors: true, msgTarget: 'qtip', msgTargets: { qtip: 1, title: 1, under: 1, side: 1, none: 1 }, noWrap: true, labelableInsertions: [ 'beforeBodyEl', 'afterBodyEl', 'beforeLabelTpl', 'afterLabelTpl', 'beforeSubTpl', 'afterSubTpl', 'beforeLabelTextTpl', 'afterLabelTextTpl', 'labelAttrTpl' ], statics: { initTip: function() { var tip = this.tip, cfg, copy; if (tip) { return; } cfg = { id: 'ext-form-error-tip', sticky: true, ui: 'form-invalid' }; if (Ext.supports.Touch) { cfg.dismissDelay = 0; cfg.anchor = 'top'; cfg.showDelay = 0; cfg.listeners = { beforeshow: function() { this.minWidth = Ext.fly(this.anchorTarget).getWidth(); } }; } tip = this.tip = Ext.create('Ext.tip.QuickTip', cfg); copy = Ext.apply({}, tip.tagConfig); copy.attribute = 'errorqtip'; tip.setTagConfig(copy); }, destroyTip: function() { this.tip = Ext.destroy(this.tip); } }, initLabelable: function() { var me = this, padding = me.padding; if (padding) { me.padding = undefined; me.extraMargins = Ext.Element.parseBox(padding); } if (Ext.isIE8) { me.restoreDisplay = Ext.Function.createDelayed(me.doRestoreDisplay, 0, me); } if (!me.activeErrorsTpl) { if (me.msgTarget === 'title') { me.activeErrorsTpl = me.plaintextActiveErrorsTpl; } else { me.activeErrorsTpl = me.htmlActiveErrorsTpl; } } me.addCls([ me.formItemCls, me.formItemCls + '-' + me.ui ]); me.lastActiveError = ''; me.enableBubble('errorchange'); }, trimLabelSeparator: function() { var me = this, separator = me.labelSeparator, label = me.fieldLabel || '', lastChar = label.substr(label.length - 1); return lastChar === separator ? label.slice(0, -1) : label; }, getFieldLabel: function() { return this.trimLabelSeparator(); }, setFieldLabel: function(label) { label = label || ''; var me = this, separator = me.labelSeparator, labelEl = me.labelEl, errorWrapEl = me.errorWrapEl, sideLabel = (me.labelAlign !== 'top'), noLabelCls = me.noLabelCls, errorWrapUnderSideLabelCls = me.errorWrapUnderSideLabelCls; me.fieldLabel = label; if (me.rendered) { if (Ext.isEmpty(label) && me.hideEmptyLabel) { me.addCls(noLabelCls); if (sideLabel && errorWrapEl) { errorWrapEl.removeCls(errorWrapUnderSideLabelCls); } } else { if (separator) { label = me.trimLabelSeparator() + separator; } labelEl.dom.firstChild.innerHTML = label; me.removeCls(noLabelCls); if (sideLabel && errorWrapEl) { errorWrapEl.addCls(errorWrapUnderSideLabelCls); } } me.updateLayout(); } }, setHideLabel: function(hideLabel) { var me = this; if (hideLabel !== me.hideLabel) { me.hideLabel = hideLabel; if (me.rendered) { me[hideLabel ? 'addCls' : 'removeCls'](me.noLabelCls); me.updateLayout(); } } }, setHideEmptyLabel: function(hideEmptyLabel) { var me = this, hide; if (hideEmptyLabel !== me.hideEmptyLabel) { me.hideEmptyLabel = hideEmptyLabel; if (me.rendered && !me.hideLabel) { hide = hideEmptyLabel && !me.getFieldLabel(); me[hide ? 'addCls' : 'removeCls'](me.noLabelCls); me.updateLayout(); } } }, getInsertionRenderData: function(data, names) { var i = names.length, name, value; while (i--) { name = names[i]; value = this[name]; if (value) { if (typeof value !== 'string') { if (!value.isTemplate) { value = Ext.XTemplate.getTpl(this, name); } value = value.apply(data); } } data[name] = value || ''; } return data; }, getLabelableRenderData: function() { var me = this, labelAlign = me.labelAlign, topLabel = (labelAlign === 'top'), rightLabel = (labelAlign === 'right'), sideError = (me.msgTarget === 'side'), underError = (me.msgTarget === 'under'), errorMsgCls = me.errorMsgCls, labelPad = me.labelPad, labelWidth = me.labelWidth, labelClsExtra = me.labelClsExtra || '', errorWrapExtraCls = sideError ? me.errorWrapSideCls : me.errorWrapUnderCls, labelStyle = '', labelInnerStyle = '', labelVisible = me.hasVisibleLabel(), autoFitErrors = me.autoFitErrors, defaultBodyWidth = me.defaultBodyWidth, bodyStyle, data; if (topLabel) { labelClsExtra += ' ' + me.topLabelCls; if (labelPad) { labelInnerStyle = 'padding-bottom:' + labelPad + 'px;'; } if (sideError && !autoFitErrors) { labelClsExtra += ' ' + me.topLabelSideErrorCls; } } else { if (rightLabel) { labelClsExtra += ' ' + me.rightLabelCls; } if (labelPad) { labelStyle += me.getHorizontalPaddingStyle() + labelPad + 'px;'; } labelStyle += 'width:' + (labelWidth + (labelPad ? labelPad : 0)) + 'px;'; labelInnerStyle = 'width:' + labelWidth + 'px'; } if (labelVisible) { if (!topLabel && underError) { errorWrapExtraCls += ' ' + me.errorWrapUnderSideLabelCls; } } if (defaultBodyWidth) { bodyStyle = 'min-width:' + defaultBodyWidth + 'px;max-width:' + defaultBodyWidth + 'px;'; } data = { id: me.id, inputId: me.getInputId(), labelCls: me.labelCls, labelClsExtra: labelClsExtra, labelStyle: labelStyle + (me.labelStyle || ''), labelInnerStyle: labelInnerStyle, labelInnerCls: me.labelInnerCls, unselectableCls: Ext.Element.unselectableCls, bodyStyle: bodyStyle, baseBodyCls: me.baseBodyCls, fieldBodyCls: me.fieldBodyCls, extraFieldBodyCls: me.extraFieldBodyCls, errorWrapCls: me.errorWrapCls, errorWrapExtraCls: errorWrapExtraCls, renderError: sideError || underError, invalidMsgCls: sideError ? me.invalidIconCls : underError ? me.invalidUnderCls : '', errorMsgCls: errorMsgCls, growCls: me.grow ? me.growCls : '', errorWrapStyle: (sideError && !autoFitErrors) ? 'visibility:hidden' : 'display:none', fieldLabel: me.getFieldLabel(), labelSeparator: me.labelSeparator }; me.getInsertionRenderData(data, me.labelableInsertions); return data; }, getHorizontalPaddingStyle: function() { return 'padding-right:'; }, beforeLabelRender: function() { var me = this; me.setFieldDefaults(me.getInherited().fieldDefaults); if (me.ownerLayout) { me.addCls(Ext.baseCSSPrefix + me.ownerLayout.type + '-form-item'); } if (!me.hasVisibleLabel()) { me.addCls(me.noLabelCls); } }, onLabelRender: function() { var me = this, style = {}, ExtElement = Ext.Element, errorWrapEl = me.errorWrapEl, margins, side; if (errorWrapEl) { errorWrapEl.setVisibilityMode((me.msgTarget === 'side' && !me.autoFitErrors) ? ExtElement.VISIBILITY : ExtElement.DISPLAY); } if (me.extraMargins) { margins = me.el.getMargin(); for (side in margins) { if (margins.hasOwnProperty(side)) { style['margin-' + side] = (margins[side] + me.extraMargins[side]) + 'px'; } } me.el.setStyle(style); } }, hasVisibleLabel: function() { if (this.hideLabel) { return false; } return !(this.hideEmptyLabel && !this.getFieldLabel()); }, getSubTplMarkup: function() { return ''; }, getInputId: function() { return ''; }, getActiveError: function() { return this.activeError || ''; }, hasActiveError: function() { return !!this.getActiveError(); }, setActiveError: function(msg) { this.setActiveErrors(msg); }, getActiveErrors: function() { return this.activeErrors || []; }, setActiveErrors: function(errors) { var me = this, errorWrapEl = me.errorWrapEl, msgTarget = me.msgTarget, isSide = msgTarget === 'side', isQtip = msgTarget === 'qtip', activeError, tpl, targetEl; errors = Ext.Array.from(errors); tpl = me.getTpl('activeErrorsTpl'); me.activeErrors = errors; activeError = me.activeError = tpl.apply({ fieldLabel: me.fieldLabel, errors: errors, listCls: Ext.baseCSSPrefix + 'list-plain' }); me.renderActiveError(); if (me.rendered) { if (isSide) { me.errorEl.dom.setAttribute('data-errorqtip', activeError); } else if (isQtip) { me.getActionEl().dom.setAttribute('data-errorqtip', activeError); } else if (msgTarget === 'title') { me.getActionEl().dom.setAttribute('title', activeError); } if (isSide || isQtip) { Ext.form.Labelable.initTip(); } if (!me.msgTargets[msgTarget]) { targetEl = Ext.get(msgTarget); if (targetEl) { targetEl.dom.innerHTML = activeError; } } } if (errorWrapEl) { errorWrapEl.setVisible(errors.length > 0); if (isSide && me.autoFitErrors) { me.labelEl.addCls(me.topLabelSideErrorCls); } me.updateLayout(); } }, unsetActiveError: function() { var me = this, errorWrapEl = me.errorWrapEl, msgTarget = me.msgTarget, targetEl, restoreDisplay = me.restoreDisplay; if (me.hasActiveError()) { delete me.activeError; delete me.activeErrors; me.renderActiveError(); if (me.rendered) { if (msgTarget === 'qtip') { me.getActionEl().dom.removeAttribute('data-errorqtip'); } else if (msgTarget === 'title') { me.getActionEl().dom.removeAttribute('title'); } if (!me.msgTargets[msgTarget]) { targetEl = Ext.get(msgTarget); if (targetEl) { targetEl.dom.innerHTML = ''; } } if (errorWrapEl) { errorWrapEl.hide(); if (msgTarget === 'side' && me.autoFitErrors) { me.labelEl.removeCls(me.topLabelSideErrorCls); } me.updateLayout(); if (restoreDisplay) { me.el.dom.style.display = 'block'; me.restoreDisplay(); } } } } }, doRestoreDisplay: function() { var el = this.el; if (el && el.dom) { el.dom.style.display = ''; } }, renderActiveError: function() { var me = this, activeError = me.getActiveError(), hasError = !!activeError; if (activeError !== me.lastActiveError) { me.lastActiveError = activeError; me.fireEvent('errorchange', me, activeError); } if (me.rendered && !me.isDestroyed && !me.preventMark) { me.toggleInvalidCls(hasError); if (me.errorEl) { me.errorEl.dom.innerHTML = activeError; } } }, toggleInvalidCls: function(hasError) { this.el[hasError ? 'addCls' : 'removeCls'](this.invalidCls); }, setFieldDefaults: function(defaults) { var key; for (key in defaults) { if (!this.hasOwnProperty(key)) { this[key] = defaults[key]; } } } }, function() { if (Ext.supports.Touch) { this.prototype.msgTarget = 'side'; } }); Ext.define('Ext.form.field.Field', { mixinId: 'field', isFormField: true, config: { validation: null, validationField: null }, disabled: false, submitValue: true, validateOnChange: true, valuePublishEvent: 'change', suspendCheckChange: 0, dirty: false, initField: function() { var me = this, valuePublishEvent = me.valuePublishEvent, len, i; me.initValue(); var badNames = [ 'tagName', 'nodeName', 'children', 'childNodes' ], name = this.name; if (name && Ext.Array.indexOf(badNames, name) > -1) { Ext.log.warn([ 'It is recommended to not use "', name, '" as a field name, because it ', 'can cause naming collisions during form submission.' ].join('')); } if (Ext.isString(valuePublishEvent)) { me.on(valuePublishEvent, me.publishValue, me); } else { for (i = 0 , len = valuePublishEvent.length; i < len; ++i) { me.on(valuePublishEvent[i], me.publishValue, me); } } }, initValue: function() { var me = this; if ('value' in me) { me.suspendCheckChange++; me.setValue(me.value); me.suspendCheckChange--; } me.initialValue = me.originalValue = me.lastValue = me.getValue(); }, getFieldIdentifier: function() { return this.isEditorComponent ? this.dataIndex : this.name; }, getName: function() { return this.name; }, getValue: function() { return this.value; }, setValue: function(value) { var me = this; me.value = value; me.checkChange(); return me; }, isEqual: function(value1, value2) { return String(value1) === String(value2); }, isEqualAsString: function(value1, value2) { return String(Ext.valueFrom(value1, '')) === String(Ext.valueFrom(value2, '')); }, getSubmitData: function() { var me = this, data = null; if (!me.disabled && me.submitValue) { data = {}; data[me.getName()] = '' + me.getValue(); } return data; }, getModelData: function(includeEmptyText, isSubmitting) { var me = this, data = null; if (!me.disabled && (me.submitValue || !isSubmitting)) { data = {}; data[me.getFieldIdentifier()] = me.getValue(); } return data; }, reset: function() { var me = this; me.beforeReset(); me.setValue(me.originalValue); me.clearInvalid(); delete me.wasValid; }, beforeReset: Ext.emptyFn, resetOriginalValue: function() { this.originalValue = this.getValue(); this.checkDirty(); }, checkChange: function() { var me = this, newVal, oldVal; if (!me.suspendCheckChange) { newVal = me.getValue(); oldVal = me.lastValue; if (!me.isDestroyed && me.didValueChange(newVal, oldVal)) { me.lastValue = newVal; me.fireEvent('change', me, newVal, oldVal); me.onChange(newVal, oldVal); } } }, didValueChange: function(newVal, oldVal) { return !this.isEqual(newVal, oldVal); }, onChange: function(newVal) { var me = this; if (me.validateOnChange) { me.validate(); } me.checkDirty(); }, publishValue: function() { var me = this; if (me.rendered && !me.getErrors().length) { me.publishState('value', me.getValue()); } }, isDirty: function() { var me = this; return !me.disabled && !me.isEqual(me.getValue(), me.originalValue); }, checkDirty: function() { var me = this, isDirty = me.isDirty(); if (isDirty !== me.wasDirty) { me.dirty = isDirty; me.fireEvent('dirtychange', me, isDirty); me.onDirtyChange(isDirty); me.wasDirty = isDirty; } }, onDirtyChange: Ext.emptyFn, getErrors: function(value) { var errors = [], validationField = this.getValidationField(), validation = this.getValidation(), result; if (validationField) { result = validationField.validate(value); if (result !== true) { errors.push(result); } } if (validation && validation !== true) { errors.push(validation); } return errors; }, isValid: function() { var me = this; return me.disabled || Ext.isEmpty(me.getErrors()); }, validate: function() { return this.checkValidityChange(this.isValid()); }, checkValidityChange: function(isValid) { var me = this; if (isValid !== me.wasValid) { me.wasValid = isValid; me.fireEvent('validitychange', me, isValid); } return isValid; }, batchChanges: function(fn) { try { this.suspendCheckChange++; fn(); } catch (pseudo) { throw pseudo; } finally { this.suspendCheckChange--; } this.checkChange(); }, isFileUpload: function() { return false; }, extractFileInput: function() { return null; }, markInvalid: Ext.emptyFn, clearInvalid: Ext.emptyFn, updateValidation: function(validation, oldValidation) { if (oldValidation) { this.validate(); } }, privates: { resetToInitialValue: function() { var me = this, originalValue = me.originalValue; me.originalValue = me.initialValue; me.reset(); me.originalValue = originalValue; } } }); Ext.define('Ext.form.field.Base', { extend: 'Ext.Component', mixins: [ 'Ext.form.Labelable', 'Ext.form.field.Field' ], xtype: 'field', alternateClassName: [ 'Ext.form.Field', 'Ext.form.BaseField' ], requires: [ 'Ext.util.DelayedTask', 'Ext.XTemplate' ], focusable: true, shrinkWrap: true, fieldSubTpl: [ ' name="{name}"', ' value="{[Ext.util.Format.htmlEncode(values.value)]}"', ' placeholder="{placeholder}"', '{%if (values.maxLength !== undefined){%} maxlength="{maxLength}"{%}%}', ' readonly="readonly"', ' disabled="disabled"', ' tabindex="{tabIdx}"', ' style="{fieldStyle}"', ' class="{fieldCls} {typeCls} {typeCls}-{ui} {editableCls} {inputCls}" autocomplete="off"/>', { disableFormats: true } ], defaultBindProperty: 'value', subTplInsertions: [ 'inputAttrTpl' ], childEls: [ 'inputEl' ], inputType: 'text', isTextInput: true, invalidText: 'The value in this field is invalid', fieldCls: Ext.baseCSSPrefix + 'form-field', focusCls: 'form-focus', dirtyCls: Ext.baseCSSPrefix + 'form-dirty', checkChangeEvents: Ext.isIE && (!document.documentMode || document.documentMode <= 9) ? [ 'change', 'propertychange', 'keyup' ] : [ 'change', 'input', 'textInput', 'keyup', 'dragdrop' ], ignoreChangeRe: /data\-errorqtip|style\.|className/, checkChangeBuffer: 50, liquidLayout: true, readOnly: false, readOnlyCls: Ext.baseCSSPrefix + 'form-readonly', validateOnBlur: true, hasFocus: false, baseCls: Ext.baseCSSPrefix + 'field', fieldBodyCls: Ext.baseCSSPrefix + 'field-body', maskOnDisable: false, stretchInputElFixed: true, initComponent: function() { var me = this; me.callParent(); me.subTplData = me.subTplData || {}; me.initLabelable(); me.initField(); if (!me.name) { me.name = me.getInputId(); } if (me.readOnly) { me.addCls(me.readOnlyCls); } me.addCls(Ext.baseCSSPrefix + 'form-type-' + me.inputType); }, getInputId: function() { return this.inputId || (this.inputId = this.id + '-inputEl'); }, getSubTplData: function(fieldData) { var me = this, type = me.inputType, inputId = me.getInputId(), data; data = Ext.apply({ ui: me.ui, id: inputId, cmpId: me.id, name: me.name || inputId, disabled: me.disabled, readOnly: me.readOnly, value: me.getRawValue(), type: type, fieldCls: me.fieldCls, fieldStyle: me.getFieldStyle(), childElCls: fieldData.childElCls, tabIdx: me.tabIndex, inputCls: me.inputCls, typeCls: Ext.baseCSSPrefix + 'form-' + (me.isTextInput ? 'text' : type), role: me.ariaRole }, me.subTplData); me.getInsertionRenderData(data, me.subTplInsertions); return data; }, getSubTplMarkup: function(fieldData) { var me = this, data = me.getSubTplData(fieldData), preSubTpl = me.getTpl('preSubTpl'), postSubTpl = me.getTpl('postSubTpl'), markup = ''; if (preSubTpl) { markup += preSubTpl.apply(data); } markup += me.getTpl('fieldSubTpl').apply(data); if (postSubTpl) { markup += postSubTpl.apply(data); } return markup; }, initRenderData: function() { return Ext.applyIf(this.callParent(), this.getLabelableRenderData()); }, setFieldStyle: function(style) { var me = this, inputEl = me.inputEl; if (inputEl) { inputEl.applyStyles(style); } me.fieldStyle = style; }, getFieldStyle: function() { var style = this.fieldStyle; return Ext.isObject(style) ? Ext.DomHelper.generateStyles(style, null, true) : style || ''; }, onRender: function() { this.callParent(arguments); this.mixins.labelable.self.initTip(); this.renderActiveError(); }, onFocusLeave: function(e) { this.callParent([ e ]); this.completeEdit(); }, completeEdit: Ext.emptyFn, isFileUpload: function() { return this.inputType === 'file'; }, getSubmitData: function() { var me = this, data = null, val; if (!me.disabled && me.submitValue) { val = me.getSubmitValue(); if (val !== null) { data = {}; data[me.getName()] = val; } } return data; }, getSubmitValue: function() { return this.processRawValue(this.getRawValue()); }, getRawValue: function() { var me = this, v = (me.inputEl ? me.inputEl.getValue() : Ext.valueFrom(me.rawValue, '')); me.rawValue = v; return v; }, setRawValue: function(value) { var me = this, rawValue = me.rawValue; if (!me.transformRawValue.$nullFn) { value = me.transformRawValue(value); } value = Ext.valueFrom(value, ''); if (rawValue === undefined || rawValue !== value || me.valueContainsPlaceholder) { me.rawValue = value; if (me.inputEl) { me.bindChangeEvents(false); me.inputEl.dom.value = value; me.bindChangeEvents(true); } if (me.rendered && me.reference) { me.publishState('rawValue', value); } } return value; }, transformRawValue: Ext.identityFn, valueToRaw: function(value) { return '' + Ext.valueFrom(value, ''); }, rawToValue: Ext.identityFn, processRawValue: Ext.identityFn, getValue: function() { var me = this, val = me.rawToValue(me.processRawValue(me.getRawValue())); me.value = val; return val; }, setValue: function(value) { var me = this; me.setRawValue(me.valueToRaw(value)); return me.mixins.field.setValue.call(me, value); }, onBoxReady: function() { var me = this; me.callParent(arguments); if (me.setReadOnlyOnBoxReady) { me.setReadOnly(me.readOnly); } }, onDisable: function() { var me = this, inputEl = me.inputEl; me.callParent(); if (inputEl) { inputEl.dom.disabled = true; if (me.hasActiveError()) { me.clearInvalid(); me.hadErrorOnDisable = true; } } if (me.wasValid === false) { me.checkValidityChange(true); } }, onEnable: function() { var me = this, inputEl = me.inputEl, mark = me.preventMark, valid; me.callParent(); if (inputEl) { inputEl.dom.disabled = false; } if (me.wasValid !== undefined) { me.forceValidation = true; me.preventMark = !me.hadErrorOnDisable; valid = me.isValid(); me.forceValidation = false; me.preventMark = mark; me.checkValidityChange(valid); } delete me.hadErrorOnDisable; }, setReadOnly: function(readOnly) { var me = this, inputEl = me.inputEl, old = me.readOnly; readOnly = !!readOnly; me[readOnly ? 'addCls' : 'removeCls'](me.readOnlyCls); me.readOnly = readOnly; if (inputEl) { inputEl.dom.readOnly = readOnly; } else if (me.rendering) { me.setReadOnlyOnBoxReady = true; } if (readOnly !== old) { me.fireEvent('writeablechange', me, readOnly); } }, fireKey: function(e) { if (e.isSpecialKey()) { this.fireEvent('specialkey', this, e); } }, initEvents: function() { var me = this, inputEl = me.inputEl, onFieldMutation = me.onFieldMutation, events = me.checkChangeEvents, len = events.length, i, event; if (inputEl) { me.mon(inputEl, Ext.supports.SpecialKeyDownRepeat ? 'keydown' : 'keypress', me.fireKey, me); for (i = 0; i < len; ++i) { event = events[i]; if (event === 'propertychange') { me.usesPropertychange = true; } if (event === 'textInput') { me.usesTextInput = true; } me.mon(inputEl, event, onFieldMutation, me); } } me.callParent(); }, onFieldMutation: function(e) { var me = this, task = me.checkChangeTask; if (!me.readOnly && !(e.type === 'propertychange' && me.ignoreChangeRe.test(e.browserEvent.propertyName))) { if (!task) { me.checkChangeTask = task = new Ext.util.DelayedTask(me.doCheckChangeTask, me); } if (!me.bindNotifyListener) { me.bindNotifyListener = Ext.on('beforebindnotify', me.onBeforeNotify, me, { destroyable: true }); } task.delay(me.checkChangeBuffer); } }, doCheckChangeTask: function() { var bindNotifyListener = this.bindNotifyListener; if (bindNotifyListener) { bindNotifyListener.destroy(); this.bindNotifyListener = null; } this.checkChange(); }, publishValue: function() { var me = this; if (me.rendered && !me.getErrors().length) { me.publishState('value', me.getValue()); } }, onDirtyChange: function(isDirty) { var me = this; me[isDirty ? 'addCls' : 'removeCls'](me.dirtyCls); if (me.rendered && me.reference) { me.publishState('dirty', isDirty); } }, isValid: function() { var me = this, disabled = me.disabled, validate = me.forceValidation || !disabled; return validate ? me.validateValue(me.processRawValue(me.getRawValue())) : disabled; }, validateValue: function(value) { var me = this, errors = me.getErrors(value), isValid = Ext.isEmpty(errors); if (!me.preventMark) { if (isValid) { me.clearInvalid(); } else { me.markInvalid(errors); } } return isValid; }, markInvalid: function(errors) { var me = this, oldMsg = me.getActiveError(), active; me.setActiveErrors(Ext.Array.from(errors)); active = me.getActiveError(); if (oldMsg !== active) { me.setError(active); } }, clearInvalid: function() { var me = this, hadError = me.hasActiveError(); delete me.hadErrorOnDisable; me.unsetActiveError(); if (hadError) { me.setError(''); } }, setError: function(error) { var me = this, msgTarget = me.msgTarget, prop; if (me.rendered) { if (msgTarget === 'title' || msgTarget === 'qtip') { prop = msgTarget === 'qtip' ? 'data-errorqtip' : 'title'; me.getActionEl().dom.setAttribute(prop, error || ''); } else { me.updateLayout(); } } }, renderActiveError: function() { var me = this, hasError = me.hasActiveError(), invalidCls = me.invalidCls + '-field'; if (me.inputEl) { me.inputEl[hasError ? 'addCls' : 'removeCls']([ invalidCls, invalidCls + '-' + me.ui ]); } me.mixins.labelable.renderActiveError.call(me); }, beforeDestroy: function() { var me = this, task = me.checkChangeTask; if (task) { task.cancel(); } me.checkChangeTask = me.bindNotifyListener = Ext.destroy(me.bindNotifyListener); me.callParent(); }, privates: { applyBind: function(bind, currentBindings) { var me = this, valueBinding = currentBindings && currentBindings.value, bindings, newValueBind; bindings = me.callParent([ bind, currentBindings ]); newValueBind = bindings.value; me.hasBindingValue = !!newValueBind; if (newValueBind !== valueBinding && me.getInherited().modelValidation) { me.updateValueBinding(bindings); } return bindings; }, applyRenderSelectors: function() { var me = this; me.callParent(); if (!me.inputEl) { me.inputEl = me.el.getById(me.getInputId()); } }, bindChangeEvents: function(active) { var method = active ? 'resumeEvent' : 'suspendEvent', inputEl = this.inputEl; if (this.usesPropertychange) { inputEl[method]('propertychange'); } if (this.usesTextInput) { inputEl[method]('textInput'); } }, getActionEl: function() { return this.inputEl || this.el; }, getFocusEl: function() { return this.inputEl; }, initRenderTpl: function() { var me = this; if (!me.hasOwnProperty('renderTpl')) { me.renderTpl = me.getTpl('labelableRenderTpl'); } return me.callParent(); }, onBeforeNotify: function() { this.checkChangeTask.cancel(); this.checkChange(); }, updateValueBinding: function(bindings) { var me = this, newBinding = bindings.value, fieldBinding = bindings.$fieldBinding; if (fieldBinding) { fieldBinding.destroy(); bindings.$fieldBinding = null; } if (newBinding && newBinding.bindValidationField) { me.fieldBinding = newBinding.bindValidationField('setValidationField', me); } } }, deprecated: { "5": { methods: { doComponentLayout: function() { this.bindChangeEvents(false); this.callParent(arguments); this.bindChangeEvents(true); } } } } }); 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' ], ariaRole: 'textbox', fieldSubTpl: [ '
style="{fieldStyle}"', ' class="{fieldCls} {fieldCls}-{ui}">{value}
', { compiled: true, disableFormats: true } ], focusable: false, readOnly: true, fieldCls: Ext.baseCSSPrefix + 'form-display-field', fieldBodyCls: Ext.baseCSSPrefix + 'form-display-field-body', htmlEncode: false, noWrap: false, validateOnChange: false, initEvents: Ext.emptyFn, submitValue: false, getValue: function() { return this.value; }, valueToRaw: function(value) { if (value || value === 0 || value === false) { return value; } else { return ''; } }, isDirty: function() { return false; }, isValid: Ext.returnTrue, validate: Ext.returnTrue, getRawValue: function() { return this.rawValue; }, setRawValue: function(value) { var me = this; value = Ext.valueFrom(value, ''); me.rawValue = value; if (me.rendered) { me.inputEl.dom.innerHTML = me.getDisplayValue(); me.updateLayout(); } return value; }, getDisplayValue: function() { var me = this, value = this.getRawValue(), display; if (me.renderer) { display = me.renderer.call(me.scope || me, value, me); } else { display = me.htmlEncode ? Ext.util.Format.htmlEncode(value) : value; } return display; }, getSubTplData: function(fieldData) { var ret = this.callParent(arguments); ret.value = this.getDisplayValue(); return ret; } }); Ext.define('Ext.layout.container.Fit', { extend: 'Ext.layout.container.Container', alternateClassName: 'Ext.layout.FitLayout', alias: 'layout.fit', itemCls: Ext.baseCSSPrefix + 'fit-item', type: 'fit', manageMargins: true, sizePolicies: { 0: { readsWidth: 1, readsHeight: 1, setsWidth: 0, setsHeight: 0 }, 1: { readsWidth: 0, readsHeight: 1, setsWidth: 1, setsHeight: 0 }, 2: { readsWidth: 1, readsHeight: 0, setsWidth: 0, setsHeight: 1 }, 3: { readsWidth: 0, readsHeight: 0, setsWidth: 1, setsHeight: 1 } }, getItemSizePolicy: function(item, ownerSizeModel) { var sizeModel = ownerSizeModel || this.owner.getSizeModel(), mode = (sizeModel.width.shrinkWrap ? 0 : 1) | (sizeModel.height.shrinkWrap ? 0 : 2); return this.sizePolicies[mode]; }, beginLayoutCycle: function(ownerContext, firstCycle) { var me = this, resetHeight = me.lastHeightModel && me.lastHeightModel.calculated, resetWidth = me.lastWidthModel && me.lastWidthModel.calculated, resetSizes = resetWidth || resetHeight, maxChildMinHeight = 0, maxChildMinWidth = 0, c, childItems, i, item, length, margins, minHeight, minWidth, style, undef; me.callParent(arguments); if (resetSizes && ownerContext.targetContext.el.dom.tagName.toUpperCase() !== 'TD') { resetSizes = resetWidth = resetHeight = false; } childItems = ownerContext.childItems; length = childItems.length; for (i = 0; i < length; ++i) { item = childItems[i]; if (firstCycle) { c = item.target; minHeight = c.minHeight; minWidth = c.minWidth; if (minWidth || minHeight) { margins = item.marginInfo || item.getMarginInfo(); minHeight += margins.height; minWidth += margins.height; if (maxChildMinHeight < minHeight) { maxChildMinHeight = minHeight; } if (maxChildMinWidth < minWidth) { maxChildMinWidth = minWidth; } } } if (resetSizes) { style = item.el.dom.style; if (resetHeight) { style.height = ''; } if (resetWidth) { style.width = ''; } } } if (firstCycle) { ownerContext.maxChildMinHeight = maxChildMinHeight; ownerContext.maxChildMinWidth = maxChildMinWidth; } c = ownerContext.target; ownerContext.overflowX = (!ownerContext.widthModel.shrinkWrap && ownerContext.maxChildMinWidth && c.scrollFlags.x) || undef; ownerContext.overflowY = (!ownerContext.heightModel.shrinkWrap && ownerContext.maxChildMinHeight && c.scrollFlags.y) || undef; }, calculate: function(ownerContext) { var me = this, childItems = ownerContext.childItems, length = childItems.length, containerSize = me.getContainerSize(ownerContext), info = { length: length, ownerContext: ownerContext, targetSize: containerSize }, shrinkWrapWidth = ownerContext.widthModel.shrinkWrap, shrinkWrapHeight = ownerContext.heightModel.shrinkWrap, overflowX = ownerContext.overflowX, overflowY = ownerContext.overflowY, scrollbars, scrollbarSize, padding, i, contentWidth, contentHeight; ownerContext.state.info = info; if (overflowX || overflowY) { scrollbars = me.getScrollbarsNeeded(overflowX && containerSize.width, overflowY && containerSize.height, ownerContext.maxChildMinWidth, ownerContext.maxChildMinHeight); if (scrollbars) { scrollbarSize = Ext.getScrollbarSize(); if (scrollbars & 1) { containerSize.height -= scrollbarSize.height; } if (scrollbars & 2) { containerSize.width -= scrollbarSize.width; } } } if (length > 0) { for (i = 0; i < length; ++i) { info.index = i; me.fitItem(childItems[i], info); } } else { info.contentWidth = info.contentHeight = 0; } if (shrinkWrapHeight || shrinkWrapWidth) { padding = ownerContext.targetContext.getPaddingInfo(); if (shrinkWrapWidth) { if (overflowY && !containerSize.gotHeight) { me.done = false; } else { contentWidth = info.contentWidth + padding.width; if (scrollbars & 2) { contentWidth += scrollbarSize.width; } if (!ownerContext.setContentWidth(contentWidth)) { me.done = false; } } } if (shrinkWrapHeight) { if (overflowX && !containerSize.gotWidth) { me.done = false; } else { contentHeight = info.contentHeight + padding.height; if (scrollbars & 1) { contentHeight += scrollbarSize.height; } if (!ownerContext.setContentHeight(contentHeight)) { me.done = false; } } } } }, fitItem: function(itemContext, info) { var me = this; if (itemContext.invalid) { me.done = false; return; } info.margins = itemContext.getMarginInfo(); info.needed = info.got = 0; me.fitItemWidth(itemContext, info); me.fitItemHeight(itemContext, info); if (info.got !== info.needed) { me.done = false; } }, fitItemWidth: function(itemContext, info) { var contentWidth, width; if (info.ownerContext.widthModel.shrinkWrap) { width = itemContext.getProp('width') + info.margins.width; contentWidth = info.contentWidth; if (contentWidth === undefined) { info.contentWidth = width; } else { info.contentWidth = Math.max(contentWidth, width); } } else if (itemContext.widthModel.calculated) { ++info.needed; if (info.targetSize.gotWidth) { ++info.got; this.setItemWidth(itemContext, info); } else { return; } } this.positionItemX(itemContext, info); }, fitItemHeight: function(itemContext, info) { var contentHeight, height; if (info.ownerContext.heightModel.shrinkWrap) { height = itemContext.getProp('height') + info.margins.height; contentHeight = info.contentHeight; if (contentHeight === undefined) { info.contentHeight = height; } else { info.contentHeight = Math.max(contentHeight, height); } } else if (itemContext.heightModel.calculated) { ++info.needed; if (info.targetSize.gotHeight) { ++info.got; this.setItemHeight(itemContext, info); } else { return; } } this.positionItemY(itemContext, info); }, positionItemX: function(itemContext, info) { var margins = info.margins; if (info.index || margins.left) { itemContext.setProp('x', margins.left); } if (margins.width) { itemContext.setProp('margin-right', margins.width); } }, positionItemY: function(itemContext, info) { var margins = info.margins; if (info.index || margins.top) { itemContext.setProp('y', margins.top); } if (margins.height) { itemContext.setProp('margin-bottom', margins.height); } }, setItemHeight: function(itemContext, info) { itemContext.setHeight(info.targetSize.height - info.margins.height); }, setItemWidth: function(itemContext, info) { itemContext.setWidth(info.targetSize.width - info.margins.width); } }); Ext.define('Ext.panel.Table', { extend: 'Ext.panel.Panel', alias: 'widget.tablepanel', requires: [ 'Ext.layout.container.Fit' ], uses: [ 'Ext.selection.RowModel', 'Ext.selection.CellModel', 'Ext.selection.CheckboxModel', 'Ext.grid.plugin.BufferedRenderer', 'Ext.grid.header.Container', 'Ext.grid.locking.Lockable', 'Ext.grid.NavigationModel' ], extraBaseCls: Ext.baseCSSPrefix + 'grid', extraBodyCls: Ext.baseCSSPrefix + 'grid-body', defaultBindProperty: 'store', layout: 'fit', ariaRole: 'grid', config: { selection: null }, publishes: [ 'selection' ], twoWayBindable: [ 'selection' ], autoLoad: false, variableRowHeight: false, numFromEdge: 2, trailingBufferZone: 10, leadingBufferZone: 20, hasView: false, viewType: null, deferRowRender: false, sortableColumns: true, multiColumnSort: false, enableLocking: false, scrollerOwner: true, enableColumnMove: true, sealedColumns: false, enableColumnResize: true, rowLines: true, bufferedRenderer: true, ownerGrid: null, colLinesCls: Ext.baseCSSPrefix + 'grid-with-col-lines', rowLinesCls: Ext.baseCSSPrefix + 'grid-with-row-lines', noRowLinesCls: Ext.baseCSSPrefix + 'grid-no-row-lines', hiddenHeaderCtCls: Ext.baseCSSPrefix + 'grid-header-ct-hidden', hiddenHeaderCls: Ext.baseCSSPrefix + 'grid-header-hidden', resizeMarkerCls: Ext.baseCSSPrefix + 'grid-resize-marker', emptyCls: Ext.baseCSSPrefix + 'grid-empty', focusable: true, constructor: function(config) { var me = this, store; me.ownerGrid = (config && config.ownerGrid) || me; me.callParent([ config ]); store = this.store; store.trackStateChanges = true; if (me.autoLoad) { store.unblockLoad(); store.load(); } }, initComponent: function() { if (this.verticalScroller) { Ext.Error.raise("The verticalScroller config is not supported."); } if (!this.viewType) { Ext.Error.raise("You must specify a viewType config."); } if (this.headers) { Ext.Error.raise("The headers config is not supported. Please specify columns instead."); } var me = this, headerCtCfg = me.columns || me.colModel || [], view, i, len, bufferedRenderer, store = me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store'), columns, viewScroller; me.enableLocking = me.enableLocking || me.hasLockedColumns(headerCtCfg); if (me.autoLoad) { me.store.blockLoad(); } if (me.plugins) { me.plugins = me.constructPlugins(); } if (me.columnLines) { me.addBodyCls(me.colLinesCls); } me.addBodyCls(me.rowLines ? me.rowLinesCls : me.noRowLinesCls); me.addBodyCls(me.extraBodyCls); if (me.enableLocking) { me.self.mixin('lockable', Ext.grid.locking.Lockable); me.injectLockable(); } else { if (headerCtCfg.isRootHeader) { if (me.hideHeaders) { headerCtCfg.setHeight(0); headerCtCfg.hiddenHeaders = true; } me.headerCt = headerCtCfg; me.headerCt.grid = me; me.headerCt.forceFit = !!me.forceFit; me.columnManager = headerCtCfg.columnManager; me.visibleColumnManager = headerCtCfg.visibleColumnManager; } else { if (Ext.isArray(headerCtCfg)) { headerCtCfg = { items: headerCtCfg }; } Ext.apply(headerCtCfg, { grid: me, forceFit: me.forceFit, sortable: me.sortableColumns, enableColumnMove: me.enableColumnMove, enableColumnResize: me.enableColumnResize, columnLines: me.columnLines, sealed: me.sealedColumns }); if (me.hideHeaders) { headerCtCfg.height = 0; headerCtCfg.hiddenHeaders = true; } if (Ext.isDefined(me.enableColumnHide)) { headerCtCfg.enableColumnHide = me.enableColumnHide; } me.headerCt = new Ext.grid.header.Container(headerCtCfg); } me.headerCt.setScrollable({ x: false, y: false }); } me.columns = columns = me.headerCt.getGridColumns(); me.scrollTask = new Ext.util.DelayedTask(me.syncHorizontalScroll, me); me.cls = (me.cls || '') + (' ' + me.extraBaseCls); delete me.autoScroll; bufferedRenderer = me.plugins && Ext.Array.findBy(me.plugins, function(p) { return p.isBufferedRenderer; }); if (bufferedRenderer) { me.bufferedRenderer = bufferedRenderer; } if (!me.hasView) { if (store.isBufferedStore && !store.getRemoteSort()) { for (i = 0 , len = columns.length; i < len; i++) { columns[i].sortable = false; } } if (me.hideHeaders) { me.headerCt.addCls(me.hiddenHeaderCtCls); me.addCls(me.hiddenHeaderCls); } me.relayHeaderCtEvents(me.headerCt); me.features = me.features || []; if (!Ext.isArray(me.features)) { me.features = [ me.features ]; } me.dockedItems = [].concat(me.dockedItems || []); me.dockedItems.unshift(me.headerCt); me.viewConfig = me.viewConfig || {}; view = me.getView(); me.items = [ view ]; me.hasView = true; if (!me.hideHeaders) { viewScroller = view.getScrollable(); if (viewScroller) { me.headerCt.getScrollable().addPartner(viewScroller, 'x'); } } me.bindStore(store, true); me.mon(view, { viewready: me.onViewReady, refresh: me.onRestoreHorzScroll, scope: me }); } me.selModel = me.view.getSelectionModel(); if (me.selModel.isRowModel) { me.selModel.on({ scope: me, lastselectedchanged: me.updateBindSelection, selectionchange: me.updateBindSelection }); } me.relayEvents(me.view, [ 'beforeitemmousedown', 'beforeitemmouseup', 'beforeitemmouseenter', 'beforeitemmouseleave', 'beforeitemclick', 'beforeitemdblclick', 'beforeitemcontextmenu', 'itemmousedown', 'itemmouseup', 'itemmouseenter', 'itemmouseleave', 'itemclick', 'itemdblclick', 'itemcontextmenu', 'beforecellclick', 'cellclick', 'beforecelldblclick', 'celldblclick', 'beforecellcontextmenu', 'cellcontextmenu', 'beforecellmousedown', 'cellmousedown', 'beforecellmouseup', 'cellmouseup', 'beforecellkeydown', 'cellkeydown', 'rowclick', 'rowdblclick', 'rowcontextmenu', 'rowmousedown', 'rowmouseup', 'rowkeydown', 'beforeitemkeydown', 'itemkeydown', 'beforeitemkeyup', 'itemkeyup', 'beforeitemkeypress', 'itemkeypress', 'beforecontainermousedown', 'beforecontainermouseup', 'beforecontainermouseover', 'beforecontainermouseout', 'beforecontainerclick', 'beforecontainerdblclick', 'beforecontainercontextmenu', 'beforecontainerkeydown', 'beforecontainerkeyup', 'beforecontainerkeypress', 'containermouseup', 'containermousedown', 'containermouseover', 'containermouseout', 'containerclick', 'containerdblclick', 'containercontextmenu', 'containerkeydown', 'containerkeyup', 'containerkeypress', 'selectionchange', 'beforeselect', 'select', 'beforedeselect', 'deselect' ]); me.callParent(arguments); me.addStateEvents([ 'columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange', 'filterchange', 'groupchange' ]); }, beforeRender: function() { var me = this, bufferedRenderer = me.bufferedRenderer; if (!me.lockable) { if (bufferedRenderer && me.getSizeModel().height.auto) { if (bufferedRenderer.isBufferedRenderer) { Ext.Error.raise('Cannot use buffered rendering with auto height'); } me.bufferedRenderer = bufferedRenderer = false; } if (bufferedRenderer && !bufferedRenderer.isBufferedRenderer) { bufferedRenderer = { xclass: 'Ext.grid.plugin.BufferedRenderer' }; Ext.copyTo(bufferedRenderer, me, 'variableRowHeight,numFromEdge,trailingBufferZone,leadingBufferZone,scrollToLoadBuffer'); me.bufferedRenderer = me.addPlugin(bufferedRenderer); } } me.callParent(arguments); }, getHeaderContainer: function() { return this.getView().getHeaderCt(); }, getColumns: function() { return this.getHeaderContainer().getGridColumns(); }, getVisibleColumns: function() { return this.getHeaderContainer().getVisibleGridColumns(); }, focus: function() { this.getView().focus(); }, disableColumnHeaders: function() { this.headerCt.disable(); }, enableColumnHeaders: function() { this.headerCt.enable(); }, hasLockedColumns: function(columns) { var i, len, column; if (columns.isRootHeader) { columns = columns.items.items; } else if (Ext.isObject(columns)) { columns = columns.items; } for (i = 0 , len = columns.length; i < len; i++) { column = columns[i]; if (!column.processed && column.locked) { return true; } } }, relayHeaderCtEvents: function(headerCt) { this.relayEvents(headerCt, [ 'columnresize', 'columnmove', 'columnhide', 'columnshow', 'columnschanged', 'sortchange', 'headerclick', 'headercontextmenu', 'headertriggerclick' ]); }, getState: function() { var me = this, state = me.callParent(), storeState = me.store.getState(); state = me.addPropertyToState(state, 'columns', me.headerCt.getColumnsState()); if (storeState) { state.storeState = storeState; } return state; }, applyState: function(state) { var me = this, sorter = state.sort, storeState = state.storeState, store = me.store, columns = state.columns; delete state.columns; me.callParent(arguments); if (columns) { me.headerCt.applyColumnsState(columns); } if (sorter) { if (store.getRemoteSort()) { store.sort({ property: sorter.property, direction: sorter.direction, root: sorter.root }, null, false); } else { store.sort(sorter.property, sorter.direction); } } else if (storeState) { store.applyState(storeState); } }, getStore: function() { return this.store; }, getView: function() { var me = this, scroll, scrollable, viewConfig; if (!me.view) { viewConfig = me.viewConfig; scroll = viewConfig.scroll || me.scroll; scrollable = me.scrollable; if (scrollable == null && viewConfig.scrollable == null && scroll !== null) { if (scroll === true || scroll === 'both') { scrollable = true; } else if (scroll === false || scroll === 'none') { scrollable = false; } else if (scroll === 'vertical') { scrollable = { x: false, y: true }; } else if (scroll === 'horizontal') { scrollable = { x: true, y: false }; } } viewConfig = Ext.apply({ grid: me, ownerGrid: me.ownerGrid, deferInitialRefresh: me.deferRowRender, variableRowHeight: me.variableRowHeight, preserveScrollOnRefresh: true, trackOver: me.trackMouseOver !== false, throttledUpdate: me.throttledUpdate === true, xtype: me.viewType, store: me.store, headerCt: me.headerCt, columnLines: me.columnLines, rowLines: me.rowLines, navigationModel: 'grid', features: me.features, panel: me, emptyText: me.emptyText || '' }, me.viewConfig); if (scrollable != null) { viewConfig.scrollable = scrollable; me.scrollable = null; } Ext.create(viewConfig); if (me.view.emptyText) { me.view.emptyText = '
' + me.view.emptyText + '
'; } me.view.getComponentLayout().headerCt = me.headerCt; me.mon(me.view, { uievent: me.processEvent, scope: me }); me.headerCt.view = me.view; if (me.hasListeners.viewcreated) { me.fireEvent('viewcreated', me, me.view); } } return me.view; }, getColumnManager: function() { return this.columnManager; }, getVisibleColumnManager: function() { return this.visibleColumnManager; }, getTopLevelColumnManager: function() { return this.ownerGrid.getColumnManager(); }, getTopLevelVisibleColumnManager: function() { return this.ownerGrid.getVisibleColumnManager(); }, setAutoScroll: Ext.emptyFn, applyScrollable: function(scrollable) { if (this.view) { this.view.setScrollable(scrollable); } return scrollable; }, getScrollable: function() { return null; }, processEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) { var header = e.position.column; if (header) { return header.processEvent.apply(header, arguments); } }, ensureVisible: function(record, options) { this.doEnsureVisible(record, options); }, scrollByDeltaY: function(yDelta, animate) { this.getView().scrollBy(0, yDelta, animate); }, scrollByDeltaX: function(xDelta, animate) { this.getView().scrollBy(xDelta, 0, animate); }, afterCollapse: function() { this.saveScrollPos(); this.callParent(arguments); }, afterExpand: function() { this.callParent(arguments); this.restoreScrollPos(); }, saveScrollPos: Ext.emptyFn, restoreScrollPos: Ext.emptyFn, onHeaderResize: function() { var scroller = this.view.getScrollable(), size; if (scroller) { size = scroller.getSize(); if (size) { scroller.setSize({ x: this.headerCt.getTableWidth(), y: size.y }); } } }, onHeaderMove: function(headerCt, header, colsToMove, fromIdx, toIdx) { var me = this; if (me.optimizedColumnMove === false) { me.view.refreshView(); } else { me.view.moveColumn(fromIdx, toIdx, colsToMove); } me.delayScroll(); }, onHeaderHide: function(headerCt, header, complete) { var view = this.view; if (!headerCt.childHideCount && view.refreshCounter) { view.refreshView(); } }, onHeaderShow: function(headerCt, header) { var view = this.view; if (view.refreshCounter) { view.refreshView(); } }, onHeadersChanged: function(headerCt, header) { var me = this; if (me.rendered && !me.reconfiguring) { me.view.refreshView(); me.delayScroll(); } }, delayScroll: function() { var target = this.view; if (target) { this.scrollTask.delay(10, null, null, [ target ]); } }, onViewReady: function() { this.fireEvent('viewready', this); }, onRestoreHorzScroll: function() { var me = this, x = me.scrollXPos; if (x) { me.syncHorizontalScroll(me, true); } }, getScrollerOwner: function() { var rootCmp = this; if (!this.scrollerOwner) { rootCmp = this.up('[scrollerOwner]'); } return rootCmp; }, getLhsMarker: function() { var me = this; return me.lhsMarker || (me.lhsMarker = Ext.DomHelper.append(me.el, { role: 'presentation', cls: me.resizeMarkerCls }, true)); }, getRhsMarker: function() { var me = this; return me.rhsMarker || (me.rhsMarker = Ext.DomHelper.append(me.el, { role: 'presentation', cls: me.resizeMarkerCls }, true)); }, getSelection: function() { return this.getSelectionModel().getSelection(); }, updateSelection: function(selection) { var me = this, sm; if (!me.ignoreNextSelection) { me.ignoreNextSelection = true; sm = me.getSelectionModel(); if (selection) { sm.select(selection); } else { sm.deselectAll(); } me.ignoreNextSelection = false; } }, updateBindSelection: function(selModel, selection) { var me = this, selected = null; if (!me.ignoreNextSelection) { me.ignoreNextSelection = true; if (selection.length) { selected = selModel.getLastSelected(); me.hasHadSelection = true; } if (me.hasHadSelection) { me.setSelection(selected); } me.ignoreNextSelection = false; } }, getNavigationModel: function() { return this.getView().getNavigationModel(); }, getSelectionModel: function() { return this.getView().getSelectionModel(); }, getScrollTarget: function() { var items = this.getScrollerOwner().query('tableview'); return items[items.length - 1]; }, syncHorizontalScroll: function(target, setBody) { var me = this, x = me.view.getScrollX(), scrollTarget; setBody = setBody === true; if (me.rendered && (setBody || x !== me.scrollXPos)) { if (setBody) { scrollTarget = me.getScrollTarget(); scrollTarget.setScrollX(x); } me.headerCt.setScrollX(x); me.scrollXPos = x; } }, onStoreLoad: Ext.emptyFn, getEditorParent: function() { return this.body; }, bindStore: function(store, initial) { var me = this, view = me.getView(); if (store) { me.store = store; if (view.store !== store) { view.bindStore(store, false); } me.mon(store, { load: me.onStoreLoad, scope: me }); me.storeRelayers = me.relayEvents(store, [ 'filterchange', 'groupchange' ]); } else { me.unbindStore(); } }, unbindStore: function() { var me = this, store = me.store, view; if (store) { me.store = null; me.mun(store, { load: me.onStoreLoad, scope: me }); Ext.destroy(me.storeRelayers); view = me.view; if (view.store) { view.bindStore(null); } } }, setColumns: function(columns) { if (columns.length || this.getColumnManager().getColumns().length) { this.reconfigure(undefined, columns); } }, setStore: function(store) { this.reconfigure(store); }, reconfigure: function(store, columns) { var me = this, oldStore = me.store, headerCt = me.headerCt, lockable = me.lockable, oldColumns = headerCt ? headerCt.items.getRange() : me.columns, view = me.getView(), block, refreshCounter; if (arguments.length === 1 && Ext.isArray(store)) { columns = store; store = null; } if (columns) { columns = Ext.Array.slice(columns); } me.reconfiguring = true; if (store) { store = Ext.StoreManager.lookup(store); } me.fireEvent('beforereconfigure', me, store, columns, oldStore, oldColumns); Ext.suspendLayouts(); if (lockable) { me.reconfigureLockable(store, columns); } else { block = view.blockRefresh; view.blockRefresh = true; if (store && store !== oldStore) { me.unbindStore(); me.bindStore(store); } if (columns) { delete me.scrollXPos; headerCt.removeAll(); headerCt.add(columns); } view.blockRefresh = block; refreshCounter = view.refreshCounter; } Ext.resumeLayouts(true); if (lockable) { me.afterReconfigureLockable(); } else if (view.refreshCounter === refreshCounter) { view.refreshView(); } me.fireEvent('reconfigure', me, store, columns, oldStore, oldColumns); delete me.reconfiguring; }, beforeDestroy: function() { var me = this, task = me.scrollTask; if (task) { task.cancel(); me.scrollTask = null; } Ext.destroy(me.focusEnterLeaveListeners); me.callParent(); }, onDestroy: function() { var me = this; if (me.lockable) { me.destroyLockable(); } me.unbindStore(); me.callParent(); me.columns = me.storeRelayers = me.columnManager = me.visibleColumnManager = null; }, destroy: function() { var me = this; me.callParent(); if (me.isDestroyed) { me.view = me.selModel = me.headerCt = null; } }, privates: { initFocusableElement: function() {}, doEnsureVisible: function(record, options) { if (this.lockable) { return this.ensureLockedVisible(record, options); } if (typeof record !== 'number' && !record.isEntity) { record = this.store.getById(record); } var me = this, callback, scope, animate, highlight, select, doFocus, view = me.getView(), domNode = view.getNode(record); if (!me.rendered || !view.refreshCounter) { return; } if (options) { callback = options.callback; scope = options.scope; animate = options.animate; highlight = options.highlight; select = options.select; doFocus = options.focus; } if (domNode) { view.getScrollable().scrollIntoView(domNode, null, animate, highlight); if (!record.isEntity) { record = view.getRecord(domNode); } if (select) { view.getSelectionModel().select(record); } if (doFocus) { view.getNavigationModel().setPosition(record, 0); } Ext.callback(callback, scope || me, [ true, record, domNode ]); } else if (view.bufferedRenderer) { view.bufferedRenderer.scrollTo(record, { animate: animate, highlight: highlight, select: select, focus: doFocus, callback: function(recordIdx, record, domNode) { Ext.callback(callback, scope || me, [ true, record, domNode ]); } }); } else { Ext.callback(callback, scope || me, [ false, null ]); } }, getFocusEl: function() { return this.getView().getFocusEl(); } } }); Ext.define('Ext.selection.Model', { extend: 'Ext.mixin.Observable', alternateClassName: 'Ext.AbstractSelectionModel', mixins: [ 'Ext.util.StoreHolder', 'Ext.mixin.Factoryable' ], alias: 'selection.abstract', factoryConfig: { defaultType: 'dataviewmodel' }, $configPrefixed: false, $configStrict: false, config: { store: null, selected: {} }, isSelectionModel: true, allowDeselect: undefined, toggleOnClick: true, selected: null, pruneRemoved: true, suspendChange: 0, ignoreRightMouseSelection: false, constructor: function(cfg) { var me = this; me.modes = { SINGLE: true, SIMPLE: true, MULTI: true }; me.callParent([ cfg ]); me.setSelectionMode(me.mode); if (me.selectionMode !== 'SINGLE') { me.allowDeselect = true; } }, updateStore: function(store, oldStore) { this.bindStore(store, !oldStore); }, applySelected: function(selected) { if (!selected.isCollection) { selected = new Ext.util.Collection(Ext.apply({ rootProperty: 'data' }, selected)); } return selected; }, onBindStore: function(store, initial) { var me = this; me.mixins.storeholder.onBindStore.call(me, [ store, initial ]); if (store && !me.preventRefresh) { me.refresh(); } }, getStoreListeners: function() { var me = this; return { add: me.onStoreAdd, clear: me.onStoreClear, remove: me.onStoreRemove, update: me.onStoreUpdate, idchanged: me.onIdChanged, load: me.onStoreLoad, refresh: me.onStoreRefresh, pageadd: me.onPageAdd, pageremove: me.onPageRemove }; }, suspendChanges: function() { ++this.suspendChange; }, resumeChanges: function() { if (this.suspendChange) { --this.suspendChange; } }, selectAll: function(suppressEvent) { var me = this, selections = me.store.getRange(), start = me.getSelection().length; me.suspendChanges(); me.doSelect(selections, true, suppressEvent); me.resumeChanges(); if (!suppressEvent && !me.isDestroyed) { me.maybeFireSelectionChange(me.getSelection().length !== start); } }, deselectAll: function(suppressEvent) { var me = this, selections = me.getSelection(), selIndexes = {}, store = me.store, start = selections.length, i, l, rec; for (i = 0 , l = selections.length; i < l; i++) { rec = selections[i]; selIndexes[rec.id] = store.indexOf(rec); } selections = Ext.Array.sort(selections, function(r1, r2) { var idx1 = selIndexes[r1.id], idx2 = selIndexes[r2.id]; return idx1 < idx2 ? -1 : 1; }); me.suspendChanges(); me.doDeselect(selections, suppressEvent); me.resumeChanges(); if (!suppressEvent && !me.isDestroyed) { me.maybeFireSelectionChange(me.getSelection().length !== start); } }, getSelectionStart: function() { return this.selectionStart; }, setSelectionStart: function(selection) { this.selectionStart = selection; }, selectWithEvent: function(record, e) { var me = this, isSelected = me.isSelected(record), shift = e.shiftKey; switch (me.selectionMode) { case 'MULTI': me.selectWithEventMulti(record, e, isSelected); break; case 'SIMPLE': me.selectWithEventSimple(record, e, isSelected); break; case 'SINGLE': me.selectWithEventSingle(record, e, isSelected); break; } if (!shift) { if (me.isSelected(record)) { me.selectionStart = record; } else { me.selectionStart = null; } } }, vetoSelection: function(e) { if (e.type !== 'keydown' && e.button !== 0) { if (this.ignoreRightMouseSelection || this.isSelected(e.record)) { return true; } } else { return e.type === 'mousedown'; } }, onNavigate: function(e) { if (!e.record || this.vetoSelection(e.keyEvent)) { return; } this.onBeforeNavigate(e); var me = this, keyEvent = e.keyEvent, ctrlKey = keyEvent.ctrlKey || e.ctrlKey, recIdx = e.recordIndex, record = e.record, lastFocused = e.previousRecord, isSelected = me.isSelected(record), from = (me.selectionStart && me.isSelected(e.previousRecord)) ? me.selectionStart : (me.selectionStart = e.previousRecord), fromIdx = e.previousRecordIndex, key = keyEvent.getCharCode(), isSpace = key === keyEvent.SPACE, direction = key === keyEvent.UP || key === keyEvent.PAGE_UP ? 'up' : (key === keyEvent.DOWN || key === keyEvent.DOWN ? 'down' : null); switch (me.selectionMode) { case 'MULTI': me.setSelectionStart(e.selectionStart); if (key === keyEvent.A && ctrlKey) { me.selected.beginUpdate(); me.selectRange(0, me.store.getCount() - 1); me.selected.endUpdate(); } else if (isSpace) { if (keyEvent.shiftKey) { me.selectRange(from, record, ctrlKey); } else { if (isSelected) { if (me.allowDeselect) { me.doDeselect(record); } } else { me.doSelect(record, ctrlKey); } } } else if (keyEvent.shiftKey && from) { if (direction === 'up' && fromIdx <= recIdx) { me.deselectRange(lastFocused, recIdx + 1); } else if (direction === 'down' && fromIdx >= recIdx) { me.deselectRange(lastFocused, recIdx - 1); } else if (from !== record) { me.selectRange(from, record, ctrlKey); } me.lastSelected = record; } else if (key) { if (!ctrlKey) { me.doSelect(record, false); } } else { me.selectWithEvent(record, keyEvent); }; break; case 'SIMPLE': if (key === keyEvent.A && ctrlKey) { me.selected.beginUpdate(); me.selectRange(0, me.store.getCount() - 1); me.selected.endUpdate(); } else if (isSelected) { me.doDeselect(record); } else { me.doSelect(record, true); }; break; case 'SINGLE': if (direction) { if (!ctrlKey) { me.doSelect(record, false); } } else { if (isSelected) { if (me.allowDeselect) { me.doDeselect(record); } } else { me.doSelect(record); } }; } if (!keyEvent.shiftKey && !me.isDestroyed) { if (me.isSelected(record)) { me.selectionStart = record; } } }, selectRange: function(startRow, endRow, keepExisting) { var me = this, store = me.store, selected = me.selected.items, result, i, len, toSelect, toDeselect, idx, rec; if (me.isLocked()) { return; } result = me.normalizeRowRange(startRow, endRow); startRow = result[0]; endRow = result[1]; toSelect = []; for (i = startRow; i <= endRow; i++) { if (!me.isSelected(store.getAt(i))) { toSelect.push(store.getAt(i)); } } if (!keepExisting) { toDeselect = []; me.suspendChanges(); for (i = 0 , len = selected.length; i < len; ++i) { rec = selected[i]; idx = store.indexOf(rec); if (idx < startRow || idx > endRow) { toDeselect.push(rec); } } for (i = 0 , len = toDeselect.length; i < len; ++i) { me.doDeselect(toDeselect[i]); } me.resumeChanges(); } if (!me.isDestroyed) { if (toSelect.length) { me.doMultiSelect(toSelect, true); } else if (toDeselect) { me.maybeFireSelectionChange(toDeselect.length > 0); } } }, deselectRange: function(startRow, endRow) { var me = this, store = me.store, result, i, toDeselect, record; if (me.isLocked()) { return; } result = me.normalizeRowRange(startRow, endRow); startRow = result[0]; endRow = result[1]; toDeselect = []; for (i = startRow; i <= endRow; i++) { record = store.getAt(i); if (me.isSelected(record)) { toDeselect.push(record); } } if (toDeselect.length) { me.doDeselect(toDeselect); } }, normalizeRowRange: function(startRow, endRow) { var store = this.store, tmp; if (!Ext.isNumber(startRow)) { startRow = store.indexOf(startRow); } startRow = Math.max(0, startRow); if (!Ext.isNumber(endRow)) { endRow = store.indexOf(endRow); } endRow = Math.min(endRow, store.getCount() - 1); if (startRow > endRow) { tmp = endRow; endRow = startRow; startRow = tmp; } return [ startRow, endRow ]; }, select: function(records, keepExisting, suppressEvent) { if (Ext.isDefined(records) && !(Ext.isArray(records) && !records.length)) { this.doSelect(records, keepExisting, suppressEvent); } }, deselect: function(records, suppressEvent) { this.doDeselect(records, suppressEvent); }, doSelect: function(records, keepExisting, suppressEvent) { var me = this, record; if (me.locked) { return; } if (typeof records === "number") { record = me.store.getAt(records); if (!record) { return; } records = [ record ]; } if (me.selectionMode === "SINGLE" && records) { record = records.length ? records[0] : records; me.doSingleSelect(record, suppressEvent); } else { me.doMultiSelect(records, keepExisting, suppressEvent); } }, doMultiSelect: function(records, keepExisting, suppressEvent) { var me = this, selected = me.selected, change = false, result, i, len, record, commit; if (me.locked) { return; } records = !Ext.isArray(records) ? [ records ] : records; len = records.length; if (!keepExisting && selected.getCount() > 0) { result = me.deselectDuringSelect(records, suppressEvent); if (me.isDestroyed) { return; } if (result[0]) { me.maybeFireSelectionChange(result[1] > 0 && !suppressEvent); return; } else { change = result[1] > 0; } } commit = function() { if (!selected.getCount()) { me.selectionStart = record; } selected.add(record); change = true; }; for (i = 0; i < len; i++) { record = records[i]; if (me.isSelected(record)) { continue; } me.onSelectChange(record, true, suppressEvent, commit); if (me.isDestroyed) { return; } } me.lastSelected = record; me.maybeFireSelectionChange(change && !suppressEvent); }, deselectDuringSelect: function(toSelect, suppressEvent) { var me = this, selected = me.selected.getRange(), len = selected.length, changed = 0, failed = false, item, i; me.suspendChanges(); me.deselectingDuringSelect = true; for (i = 0; i < len; ++i) { item = selected[i]; if (!Ext.Array.contains(toSelect, item)) { if (me.doDeselect(item, suppressEvent)) { ++changed; } else { failed = true; } } if (me.isDestroyed) { failed = true; changed = 0; break; } } me.deselectingDuringSelect = false; me.resumeChanges(); return [ failed, changed ]; }, doDeselect: function(records, suppressEvent) { var me = this, selected = me.selected, i = 0, len, record, attempted = 0, accepted = 0, commit; if (me.locked || !me.store) { return false; } if (typeof records === "number") { record = me.store.getAt(records); if (!record) { return false; } records = [ record ]; } else if (!Ext.isArray(records)) { records = [ records ]; } commit = function() { ++accepted; selected.remove(record); if (record === me.selectionStart) { me.selectionStart = null; } }; len = records.length; me.suspendChanges(); for (; i < len; i++) { record = records[i]; if (me.isSelected(record)) { if (me.lastSelected === record) { me.lastSelected = selected.last(); } ++attempted; me.onSelectChange(record, false, suppressEvent, commit); if (me.isDestroyed) { return false; } } } me.resumeChanges(); me.maybeFireSelectionChange(accepted > 0 && !suppressEvent); return accepted === attempted; }, doSingleSelect: function(record, suppressEvent) { var me = this, changed = false, selected = me.selected, commit; if (me.locked) { return; } if (me.isSelected(record)) { return; } commit = function() { if (selected.getCount()) { me.suspendChanges(); var result = me.deselectDuringSelect([ record ], suppressEvent); if (me.isDestroyed) { return; } me.resumeChanges(); if (result[0]) { return false; } } me.lastSelected = record; if (!selected.getCount()) { me.selectionStart = record; } selected.add(record); changed = true; }; me.onSelectChange(record, true, suppressEvent, commit); if (changed && !me.isDestroyed) { me.maybeFireSelectionChange(!suppressEvent); } }, maybeFireSelectionChange: function(fireEvent) { var me = this; if (fireEvent && !me.suspendChange) { me.fireEvent('selectionchange', me, me.getSelection()); } }, getLastSelected: function() { return this.lastSelected; }, getSelection: function() { return this.selected.getRange(); }, getSelectionMode: function() { return this.selectionMode; }, setSelectionMode: function(selMode) { selMode = selMode ? selMode.toUpperCase() : 'SINGLE'; this.selectionMode = this.modes[selMode] ? selMode : 'SINGLE'; }, isLocked: function() { return this.locked; }, setLocked: function(locked) { this.locked = !!locked; }, isRangeSelected: function(startRow, endRow) { var me = this, store = me.store, i, result; result = me.normalizeRowRange(startRow, endRow); startRow = result[0]; endRow = result[1]; for (i = startRow; i <= endRow; i++) { if (!me.isSelected(store.getAt(i))) { return false; } } return true; }, isSelected: function(record) { record = Ext.isNumber(record) ? this.store.getAt(record) : record; return this.selected.contains(record); }, hasSelection: function() { var selected = this.getSelected(); return !!(selected && selected.getCount()); }, refresh: function() { var me = this, store = me.store, toBeSelected = [], toBeReAdded = [], oldSelections = me.getSelection(), len = oldSelections.length, selected = me.getSelected(), change, d, storeData, selection, rec, i; if (!store || !(selected.isCollection || selected.isRows) || !selected.getCount()) { return; } storeData = store.getData(); if (storeData.getSource) { d = storeData.getSource(); if (d) { storeData = d; } } me.refreshing = true; selected.beginUpdate(); me.suspendChanges(); for (i = 0; i < len; i++) { selection = oldSelections[i]; rec = storeData.get(selection.getId()); if (rec) { toBeSelected.push(rec); } else if (!me.pruneRemoved) { toBeReAdded.push(selection); } if (me.mode === 'SINGLE' && toBeReAdded.length) { break; } } if (selected.getCount() !== (toBeSelected.length + toBeReAdded.length)) { change = true; } me.clearSelections(); if (toBeSelected.length) { me.doSelect(toBeSelected, false, true); } if (toBeReAdded.length) { selected.add(toBeReAdded); if (!me.lastSelected) { me.lastSelected = toBeReAdded[toBeReAdded.length - 1]; } } me.resumeChanges(); if (change) { selected.endUpdate(); } else { selected.updating--; } me.refreshing = false; me.maybeFireSelectionChange(change); }, clearSelections: function() { var selected = this.getSelected(); if (selected) { selected.clear(); } this.lastSelected = null; }, onStoreAdd: Ext.emptyFn, onStoreClear: function() { if (!this.store.isLoading() && this.hasSelection()) { this.clearSelections(); this.maybeFireSelectionChange(true); } }, onStoreRemove: function(store, records, index, isMove) { var me = this, toDeselect = records, i, len, rec, moveMap; if (me.selectionStart && Ext.Array.contains(records, me.selectionStart)) { me.selectionStart = null; } if (isMove || me.locked || !me.pruneRemoved) { return; } moveMap = store.isMoving(null, true); if (moveMap) { toDeselect = null; for (i = 0 , len = records.length; i < len; ++i) { rec = records[i]; if (!moveMap[rec.id]) { (toDeselect || (toDeselect = [])).push(rec); } } } if (toDeselect) { me.deselect(toDeselect); } }, onPageRemove: function(pageMap, pageNumber, records) { this.onStoreRemove(this.store, records); }, onPageAdd: function(pageMap, pageNumber, records) { var len = records.length, i, record; for (i = 0; i < len; i++) { record = records[i]; if (this.selected.get(record.id)) { this.selected.replace(record); } } }, getCount: function() { return this.selected.getCount(); }, onUpdate: Ext.emptyFn, destroy: function() { var me = this; me.clearListeners(); me.clearSelections(); me.bindStore(null); me.selected = Ext.destroy(me.selected); me.callParent(); }, onStoreUpdate: Ext.emptyFn, onIdChanged: function(store, rec, oldId, newId) { this.selected.updateKey(rec, oldId); }, onStoreRefresh: function() { this.updateSelectedInstances(this.selected); }, updateSelectedInstances: function(selected) { var me = this, store = me.getStore(), lastSelected = me.lastSelected, removeCount = 0, prune = me.pruneRemovedOnRefresh(), items, length, i, selectedRec, rec, lastSelectedChanged; if (store.isBufferedStore) { return; } items = selected.getRange(); length = items.length; if (lastSelected) { me.lastSelected = store.getById(lastSelected.id); lastSelectedChanged = me.lastSelected !== lastSelected; } me.refreshing = true; for (i = 0; i < length; ++i) { selectedRec = items[i]; rec = store.getById(selectedRec.id); if (rec) { if (rec !== selectedRec) { selected.replace(rec); } } else if (prune) { selected.remove(selectedRec); ++removeCount; } } me.refreshing = false; me.maybeFireSelectionChange(removeCount > 0); if (lastSelectedChanged) { me.fireEvent('lastselectedchanged', me, me.getSelection(), me.lastSelected); } }, pruneRemovedOnRefresh: function() { return this.pruneRemoved; }, onStoreLoad: Ext.emptyFn, onSelectChange: function(record, isSelected, suppressEvent, commitFn) { var me = this, eventName = isSelected ? 'select' : 'deselect'; if ((suppressEvent || me.fireEvent('before' + eventName, me, record)) !== false && commitFn() !== false) { if (!suppressEvent) { me.fireEvent(eventName, me, record); } } }, onEditorKey: Ext.emptyFn, beforeViewRender: function(view) { Ext.Array.include(this.views || (this.views = []), view); }, onHeaderClick: Ext.emptyFn, resolveListenerScope: function(defaultScope) { var view = this.view, scope; if (view) { scope = view.resolveSatelliteListenerScope(this, defaultScope); } return scope || this.callParent([ defaultScope ]); }, bindComponent: Ext.emptyFn, privates: { onBeforeNavigate: Ext.privateFn, selectWithEventMulti: function(record, e, isSelected) { var me = this, shift = e.shiftKey, ctrl = e.ctrlKey, start = shift ? (me.getSelectionStart()) : null, selected = me.getSelection(), len = selected.length, toDeselect, i, item; if (shift && start) { me.selectRange(start, record, ctrl); } else if (ctrl && isSelected) { if (me.allowDeselect) { me.doDeselect(record, false); } } else if (ctrl) { me.doSelect(record, true, false); } else if (isSelected && !shift && !ctrl && len > 1) { if (me.allowDeselect) { toDeselect = []; for (i = 0; i < len; ++i) { item = selected[i]; if (item !== record) { toDeselect.push(item); } } me.doDeselect(toDeselect); } } else if (!isSelected) { me.doSelect(record, false); } }, selectWithEventSimple: function(record, e, isSelected) { if (isSelected) { this.doDeselect(record); } else { this.doSelect(record, true); } }, selectWithEventSingle: function(record, e, isSelected) { var me = this, allowDeselect = me.allowDeselect; if (allowDeselect && !e.ctrlKey) { allowDeselect = me.toggleOnClick; } if (allowDeselect && isSelected) { me.doDeselect(record); } else { me.doSelect(record, false); } } } }); Ext.define('Ext.selection.DataViewModel', { extend: 'Ext.selection.Model', alias: 'selection.dataviewmodel', requires: [ 'Ext.util.KeyNav' ], deselectOnContainerClick: true, bindComponent: function(view) { var me = this, viewListeners; if (me.view !== view) { if (me.view) { me.navigationModel = null; Ext.destroy(me.viewListeners, me.navigationListeners); } me.view = view; if (view) { viewListeners = me.getViewListeners(); viewListeners.scope = me; viewListeners.destroyable = true; me.navigationModel = view.getNavigationModel(); me.viewListeners = view.on(viewListeners); me.navigationListeners = me.navigationModel.on({ navigate: me.onNavigate, scope: me, destroyable: true }); } } }, getViewListeners: function() { var me = this, eventListeners = {}; eventListeners[me.view.triggerCtEvent] = me.onContainerClick; return eventListeners; }, onUpdate: function(record) { var view = this.view; if (view && this.isSelected(record)) { view.onItemSelect(record); } }, onContainerClick: function() { if (this.deselectOnContainerClick) { this.deselectAll(); } }, onSelectChange: function(record, isSelected, suppressEvent, commitFn) { var me = this, view = me.view, eventName = isSelected ? 'select' : 'deselect', recordIndex = me.store.indexOf(record); if ((suppressEvent || me.fireEvent('before' + eventName, me, record, recordIndex)) !== false && commitFn() !== false) { if (view) { if (isSelected) { view.onItemSelect(record); } else { view.onItemDeselect(record); } } if (!suppressEvent) { me.fireEvent(eventName, me, record, recordIndex); } } }, destroy: function() { this.bindComponent(); Ext.destroy(this.keyNav); this.callParent(); } }); Ext.define('Ext.view.NavigationModel', { mixins: [ 'Ext.util.Observable', 'Ext.mixin.Factoryable' ], alias: 'view.navigation.default', focusCls: Ext.baseCSSPrefix + 'view-item-focused', constructor: function() { this.mixins.observable.constructor.call(this); }, bindComponent: function(view) { if (this.view !== view) { this.view = view; this.bindView(view); } }, bindView: function(view) { var me = this, dataSource = view.dataSource, listeners; me.initKeyNav(view); if (me.dataSource !== dataSource) { me.dataSource = dataSource; listeners = me.getStoreListeners(); listeners.destroyable = true; me.dataSourceListeners = view.dataSource.on(listeners); } listeners = me.getViewListeners(); listeners.destroyable = true; me.viewListeners = me.viewListeners || []; me.viewListeners.push(view.on(listeners)); }, getStoreListeners: function() { var me = this; return { clear: me.onStoreClear, remove: me.onStoreRemove, scope: me }; }, getViewListeners: function() { var me = this; return { containermousedown: me.onContainerMouseDown, itemmousedown: me.onItemMouseDown, itemclick: me.onItemClick, itemcontextmenu: me.onItemMouseDown, scope: me }; }, initKeyNav: function(view) { var me = this; me.keyNav = new Ext.util.KeyNav({ target: view, ignoreInputFields: true, eventName: 'itemkeydown', defaultEventAction: 'stopEvent', processEvent: me.processViewEvent, up: me.onKeyUp, down: me.onKeyDown, right: me.onKeyRight, left: me.onKeyLeft, pageDown: me.onKeyPageDown, pageUp: me.onKeyPageUp, home: me.onKeyHome, end: me.onKeyEnd, tab: me.onKeyTab, space: me.onKeySpace, enter: me.onKeyEnter, A: { ctrl: true, handler: me.onSelectAllKeyPress }, scope: me }); }, processViewEvent: function(view, record, node, index, event) { return event; }, addKeyBindings: function(binding) { this.keyNav.addBindings(binding); }, enable: function() { this.keyNav.enable(); this.disabled = false; }, disable: function() { this.keyNav.disable(); this.disabled = true; }, onContainerMouseDown: function(view, mousedownEvent) { if (this.view.containsFocus) { mousedownEvent.preventDefault(); } }, onItemMouseDown: function(view, record, item, index, mousedownEvent) { var parentEvent = mousedownEvent.parentEvent; if (!parentEvent || parentEvent.type !== 'touchstart') { this.setPosition(index); } }, onItemClick: function(view, record, item, index, clickEvent) { if (this.record === record) { this.fireNavigateEvent(clickEvent); } else { this.setPosition(index, clickEvent); } }, beforeViewRefresh: function() { this.focusRestorePosition = this.view.dataSource.isBufferedStore ? this.recordIndex : this.record; }, onViewRefresh: function() { if (this.focusRestorePosition != null) { this.setPosition(this.focusRestorePosition); this.focusRestorePosition = null; } }, onStoreClear: function() { this.setPosition(); }, onStoreRemove: function() { this.setPosition(this.getRecord(), null, null, true); }, setPosition: function(recordIndex, keyEvent, suppressEvent, preventNavigation) { var me = this, view = me.view, selModel = view.getSelectionModel(), dataSource = view.dataSource, newRecord, newRecordIndex; if (recordIndex == null || !view.all.getCount()) { me.record = me.recordIndex = null; } else { if (typeof recordIndex === 'number') { newRecordIndex = Math.max(Math.min(recordIndex, dataSource.getCount() - 1), 0); newRecord = dataSource.getAt(recordIndex); } else if (recordIndex.isEntity) { newRecord = dataSource.getById(recordIndex.id); newRecordIndex = dataSource.indexOf(newRecord); if (newRecordIndex === -1) { newRecord = dataSource.getAt(0); newRecordIndex = 0; } } else if (recordIndex.tagName) { newRecord = view.getRecord(recordIndex); newRecordIndex = dataSource.indexOf(newRecord); } else { newRecord = newRecordIndex = null; } } if (newRecord === me.record) { me.recordIndex = newRecordIndex; return me.focusPosition(newRecordIndex); } if (me.item) { me.item.removeCls(me.focusCls); } me.previousRecordIndex = me.recordIndex; me.previousRecord = me.record; me.previousItem = me.item; me.recordIndex = newRecordIndex; me.record = newRecord; preventNavigation = preventNavigation || me.record === me.lastFocused; if (newRecord) { me.focusPosition(me.recordIndex); } else { me.item = null; } if (!suppressEvent) { selModel.fireEvent('focuschange', selModel, me.previousRecord, me.record); } if (!preventNavigation && keyEvent) { me.fireNavigateEvent(keyEvent); } }, focusPosition: function(recordIndex) { var me = this; if (recordIndex != null && recordIndex !== -1) { if (recordIndex.isEntity) { recordIndex = me.view.dataSource.indexOf(recordIndex); } me.item = me.view.all.item(recordIndex); if (me.item) { me.lastFocused = me.record; me.lastFocusedIndex = me.recordIndex; me.focusItem(me.item); } else { me.record = null; } } else { me.item = null; } }, focusItem: function(item) { item.addCls(this.focusCls); item.focus(); }, getPosition: function() { return this.record ? this.recordIndex : null; }, getRecordIndex: function() { return this.recordIndex; }, getItem: function() { return this.item; }, getRecord: function() { return this.record; }, getLastFocused: function() { if (this.view.dataSource.indexOf(this.lastFocused) === -1) { return null; } return this.lastFocused; }, onKeyUp: function(keyEvent) { var newPosition = this.recordIndex - 1; if (newPosition < 0) { newPosition = this.view.all.getCount() - 1; } this.setPosition(newPosition, keyEvent); }, onKeyDown: function(keyEvent) { var newPosition = this.recordIndex + 1; if (newPosition > this.view.all.getCount() - 1) { newPosition = 0; } this.setPosition(newPosition, keyEvent); }, onKeyRight: function(keyEvent) { var newPosition = this.recordIndex + 1; if (newPosition > this.view.all.getCount() - 1) { newPosition = 0; } this.setPosition(newPosition, keyEvent); }, onKeyLeft: function(keyEvent) { var newPosition = this.recordIndex - 1; if (newPosition < 0) { newPosition = this.view.all.getCount() - 1; } this.setPosition(newPosition, keyEvent); }, onKeyPageDown: Ext.emptyFn, onKeyPageUp: Ext.emptyFn, onKeyHome: function(keyEvent) { this.setPosition(0, keyEvent); }, onKeyEnd: function(keyEvent) { this.setPosition(this.view.all.getCount() - 1, keyEvent); }, onKeyTab: function(keyEvent) { var view = this.view; view.toggleChildrenTabbability(false); return true; }, onKeySpace: function(keyEvent) { this.fireNavigateEvent(keyEvent); }, onKeyEnter: function(keyEvent) { keyEvent.stopEvent(); keyEvent.view.fireEvent('itemclick', keyEvent.view, keyEvent.record, keyEvent.item, keyEvent.recordIndex, keyEvent); }, onSelectAllKeyPress: function(keyEvent) { this.fireNavigateEvent(keyEvent); }, fireNavigateEvent: function(keyEvent) { var me = this; me.fireEvent('navigate', { navigationModel: me, keyEvent: keyEvent, previousRecordIndex: me.previousRecordIndex, previousRecord: me.previousRecord, previousItem: me.previousItem, recordIndex: me.recordIndex, record: me.record, item: me.item }); }, destroy: function() { var me = this; Ext.destroy(me.dataSourceListeners, me.viewListeners, me.keyNav); me.keyNav = me.dataSourceListeners = me.viewListeners = me.dataSource = null; me.callParent(); } }); Ext.define('Ext.view.AbstractView', { extend: 'Ext.Component', requires: [ 'Ext.LoadMask', 'Ext.CompositeElementLite', 'Ext.selection.DataViewModel', 'Ext.view.NavigationModel' ], mixins: [ 'Ext.util.StoreHolder' ], inheritableStatics: { getRecord: function(node) { return this.getBoundView(node).getRecord(node); }, getBoundView: function(node) { return Ext.getCmp(node.getAttribute('data-boundView')); } }, defaultBindProperty: 'store', renderBuffer: document.createElement('div'), statics: { updateDelay: 200, queueRecordChange: function(view, store, record, operation, modifiedFieldNames) { var me = this, changeQueue = me.changeQueue || (me.changeQueue = {}), recId = record.internalId, recChange, updated, len, i, fieldName, value, checkForReversion; recChange = changeQueue[recId] || (changeQueue[recId] = { operation: operation, record: record, data: {}, views: [] }); updated = recChange.data; Ext.Array.include(recChange.views, view); if (modifiedFieldNames && (len = modifiedFieldNames.length)) { for (i = 0; i < len; i++) { fieldName = modifiedFieldNames[i]; value = record.data[fieldName]; if (updated.hasOwnProperty(fieldName)) { if (record.isEqual(updated[fieldName], value)) { delete updated[fieldName]; checkForReversion = true; } } else { updated[fieldName] = value; } } if (checkForReversion && !Ext.Object.getKeys(updated).length) { delete changeQueue[recId]; } } else { Ext.apply(updated, record.data); } if (!me.flushQueueTask) { me.flushQueueTask = Ext.util.TaskManager.newTask({ run: Ext.global.requestAnimationFrame ? Ext.Function.createAnimationFrame(me.onFlushTick, me) : Ext.Function.bind(me.onFlushTick, me), interval: Ext.view.AbstractView.updateDelay, repeat: 1 }); } me.flushQueueTask.start(); }, onFlushTick: function() { Ext.AnimationQueue.start(this.flushChangeQueue, this); }, flushChangeQueue: function() { var me = this, dirtyViews, len, changeQueue, recChange, recId, i, view; if (Ext.isScrolling) { me.flushQueueTask.start(); return; } changeQueue = me.changeQueue; this.changeQueue = {}; for (recId in changeQueue) { recChange = changeQueue[recId]; dirtyViews = recChange.views; len = dirtyViews.length; for (i = 0; i < len; i++) { view = dirtyViews[i]; if (!view.isDestroyed) { view.handleUpdate(view.dataSource, recChange.record, recChange.operation, Ext.Object.getKeys(recChange.data)); } } } Ext.AnimationQueue.stop(me.flushChangeQueue, me); } }, config: { selection: null, store: 'ext-empty-store', navigationModel: { type: 'default' }, selectionModel: { type: 'dataviewmodel' } }, publishes: [ 'selection' ], twoWayBindable: [ 'selection' ], throttledUpdate: false, deferInitialRefresh: false, itemCls: Ext.baseCSSPrefix + 'dataview-item', loadingText: 'Loading...', loadMask: true, loadingUseMsg: true, selectedItemCls: Ext.baseCSSPrefix + 'item-selected', emptyText: "", deferEmptyText: true, trackOver: false, blockRefresh: false, preserveScrollOnRefresh: false, ariaRole: 'listbox', itemAriaRole: 'option', last: false, focusable: true, tabIndex: 0, triggerEvent: 'itemclick', triggerCtEvent: 'containerclick', refreshNeeded: true, updateSuspendCounter: 0, addCmpEvents: Ext.emptyFn, constructor: function(config) { if (config && config.selModel) { config.selectionModel = config.selModel; } this.callParent([ config ]); }, 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.itemAriaRole); me.tpl = new Ext.XTemplate(itemTpl, memberFn); } if (!isDef(me.tpl) || !isDef(me.itemSelector)) { Ext.Error.raise({ sourceClass: 'Ext.view.View', tpl: me.tpl, itemSelector: me.itemSelector, msg: "DataView requires both tpl and itemSelector configurations to be defined." }); } me.callParent(); me.tpl = me.getTpl('tpl'); if (isDef(me.overCls) || isDef(me.overClass)) { if (Ext.isDefined(Ext.global.console)) { Ext.global.console.warn('Ext.view.View: Using the deprecated overCls or overClass configuration. Use overItemCls instead.'); } me.overItemCls = me.overCls || me.overClass; delete me.overCls; delete me.overClass; } if (isDef(me.selectedCls) || isDef(me.selectedClass)) { if (Ext.isDefined(Ext.global.console)) { Ext.global.console.warn('Ext.view.View: Using the deprecated selectedCls or selectedClass configuration. Use selectedItemCls instead.'); } me.selectedItemCls = me.selectedCls || me.selectedClass; delete me.selectedCls; delete me.selectedClass; } if (me.overItemCls) { me.trackOver = true; } me.addCmpEvents(); me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store'); if (!me.dataSource) { me.dataSource = me.store; } me.getNavigationModel().bindComponent(this); me.bindStore(me.dataSource, true, 'dataSource'); if (!me.all) { me.all = new Ext.CompositeElementLite(); } me.scrollState = { top: 0, left: 0 }; me.savedTabIndexAttribute = 'data-savedtabindex-' + me.id; }, getElConfig: function() { var result = this.mixins.renderable.getElConfig.call(this); if (this.focusable) { result.tabIndex = 0; } return result; }, onRender: function() { var mask = this.loadMask; this.callParent(arguments); if (mask) { this.createMask(mask); } }, beforeLayout: function() { var me = this; me.callParent(arguments); if (me.refreshNeeded && !me.pendingRefresh) { if (me.refreshCounter) { me.refresh(); } else { me.doFirstRefresh(me.dataSource); } } }, onMaskBeforeShow: function() { var me = this, loadingHeight = me.loadingHeight; if (loadingHeight && loadingHeight > me.getHeight()) { me.hasLoadingHeight = true; me.oldMinHeight = me.minHeight; me.minHeight = loadingHeight; me.updateLayout(); } }, onMaskHide: function() { var me = this; if (!me.destroying && me.hasLoadingHeight) { me.minHeight = me.oldMinHeight; me.updateLayout(); delete me.hasLoadingHeight; } }, beforeRender: function() { this.callParent(arguments); this.getSelectionModel().beforeViewRender(this); }, afterRender: function() { this.callParent(arguments); if (this.focusable) { this.focusEl = this.el; } }, getRefItems: function() { var mask = this.loadMask, result = []; if (mask && mask.isComponent) { result.push(mask); } return result; }, getSelection: function() { return this.getSelectionModel().getSelection(); }, updateSelection: function(selection) { var me = this, sm; if (!me.ignoreNextSelection) { me.ignoreNextSelection = true; sm = me.getSelectionModel(); if (selection) { sm.select(selection); } else { sm.deselectAll(); } me.ignoreNextSelection = false; } }, updateBindSelection: function(selModel, selection) { var me = this, selected = null; if (!me.ignoreNextSelection) { me.ignoreNextSelection = true; if (selection.length) { selected = selModel.getLastSelected(); me.hasHadSelection = true; } if (me.hasHadSelection) { me.setSelection(selected); } me.ignoreNextSelection = false; } }, applySelectionModel: function(selModel, oldSelModel) { var me = this, mode; if (oldSelModel) { oldSelModel.un({ scope: me, lastselectedchanged: me.updateBindSelection, selectionchange: me.updateBindSelection }); Ext.destroy(me.selModelRelayer); selModel = Ext.Factory.selection(selModel); } else { if (selModel && selModel.isSelectionModel) { selModel.locked = me.disableSelection; } else { if (me.simpleSelect) { mode = 'SIMPLE'; } else if (me.multiSelect) { mode = 'MULTI'; } else { mode = 'SINGLE'; } if (typeof selModel === 'string') { selModel = { type: selModel }; } selModel = Ext.Factory.selection(Ext.apply({ allowDeselect: me.allowDeselect || me.multiSelect, mode: mode, locked: me.disableSelection }, selModel)); } } me.selModelRelayer = me.relayEvents(selModel, [ 'selectionchange', 'beforeselect', 'beforedeselect', 'select', 'deselect', 'focuschange' ]); selModel.on({ scope: me, lastselectedchanged: me.updateBindSelection, selectionchange: me.updateBindSelection }); return selModel; }, updateSelectionModel: function(selectionModel) { this.selModel = selectionModel; }, applyNavigationModel: function(navigationModel) { return Ext.Factory.viewNavigation(navigationModel); }, onFocusEnter: function(e) { var me = this, navigationModel = me.getNavigationModel(), focusPosition; if (!me.itemFocused && me.all.getCount()) { focusPosition = navigationModel.getLastFocused(); navigationModel.setPosition(focusPosition || 0, e.event, null, !focusPosition); me.itemFocused = navigationModel.getPosition() != null; } if (me.itemFocused) { this.el.dom.setAttribute('tabindex', '-1'); } }, onFocusLeave: function(e) { var me = this; if (me.itemFocused) { me.getNavigationModel().setPosition(null, e.event, null, true); me.itemFocused = false; me.el.dom.setAttribute('tabindex', 0); } }, onRemoved: function(isDestroying) { this.callParent([ isDestroying ]); this.onFocusLeave({}); }, refresh: function() { var me = this, items = me.all, prevItemCount = items.getCount(), refreshCounter = me.refreshCounter, targetEl, overflowEl, dom, records, selModel = me.getSelectionModel(), navModel = me.getNavigationModel(), preserveScroll = refreshCounter && items.getCount() && me.preserveScrollOnRefresh && !me.bufferedRenderer, scrollPos; if (!me.rendered || me.isDestroyed || me.preventRefresh) { return; } if (!me.hasListeners.beforerefresh || me.fireEvent('beforerefresh', me) !== false) { me.refreshing = true; navModel.beforeViewRefresh(me); targetEl = me.getTargetEl(); records = me.getViewRange(); dom = targetEl.dom; if (preserveScroll) { overflowEl = me.getOverflowEl(); scrollPos = overflowEl.getScroll(); } if (refreshCounter) { me.clearViewEl(); me.refreshCounter++; } else { me.refreshCounter = 1; } me.tpl.append(targetEl, me.collectData(records, items.startIndex || 0)); if (records.length < 1) { me.addEmptyText(); items.clear(); } else { me.collectNodes(targetEl.dom); me.updateIndexes(0); } navModel.onViewRefresh(); if (me.refreshSelmodelOnRefresh !== false) { selModel.refresh(); } me.refreshNeeded = false; me.refreshSize(items.getCount() !== prevItemCount); me.fireEvent('refresh', me, records); if (preserveScroll) { overflowEl.setScrollLeft(scrollPos.left); overflowEl.setScrollTop(scrollPos.top); } if (!me.viewReady) { me.viewReady = true; me.fireEvent('viewready', me); } me.refreshing = false; me.refreshScroll(); } }, addEmptyText: function() { var me = this; if (me.emptyText && !me.getStore().isLoading() && (!me.deferEmptyText || me.refreshCounter > 1)) { me.emptyEl = Ext.core.DomHelper.insertHtml('beforeEnd', me.getTargetEl().dom, me.emptyText); } }, toggleChildrenTabbability: function(enableTabbing) { var attr = this.savedTabIndexAttribute, focusEl = this.getTargetEl(); if (enableTabbing) { focusEl.restoreChildrenTabbableState(attr); } else { focusEl.saveChildrenTabbableState(attr); } }, collectNodes: function(targetEl) { var all = this.all; all.fill(Ext.fly(targetEl).query(this.getItemSelector()), all.startIndex || 0); if (this.focusable) { all.set({ tabindex: '-1' }); } }, getViewRange: function() { return this.dataSource.getRange(); }, refreshSize: function(forceLayout) { var me = this, sizeModel = me.getSizeModel(), scroller = me.getScrollable(); if (sizeModel.height.shrinkWrap || sizeModel.width.shrinkWrap || forceLayout) { me.updateLayout(); } else if (me.touchScroll && !me.bufferedRenderer) { if (scroller) { scroller.refresh(); } else { me.on({ boxready: me.refreshScroll, scope: me, single: true }); } } }, onResize: function() { var me = this, scroller = me.getScrollable(); if (scroller && !me._hasScrollListener) { scroller.on({ scroll: me.onViewScroll, scope: me, onFrame: !!Ext.global.requestAnimationFrame }); me._hasScrollListener = true; } this.callParent(arguments); }, clearViewEl: function() { var me = this, targetEl = me.getTargetEl(), nodeContainerIsTarget = me.getNodeContainer() === targetEl; me.clearEmptyEl(); me.all.clear(!nodeContainerIsTarget); if (nodeContainerIsTarget) { targetEl.dom.innerHTML = ''; } }, clearEmptyEl: function() { var emptyEl = this.emptyEl; if (emptyEl) { Ext.removeNode(emptyEl); } this.emptyEl = null; }, onViewScroll: function(scroller, x, y) { this.fireEvent('scroll', this, x, y); }, saveScrollState: function() { var me = this, state = me.scrollState; if (me.rendered) { state.left = me.getScrollX(); state.top = me.getScrollY(); } }, restoreScrollState: function() { var me = this, state = me.scrollState; if (me.rendered) { me.setScrollX(state.left); me.setScrollY(state.top); } }, prepareData: function(data, index, record) { var associatedData, attr, hasCopied; if (record) { associatedData = record.getAssociatedData(); for (attr in associatedData) { if (associatedData.hasOwnProperty(attr)) { if (!hasCopied) { data = Ext.Object.chain(data); hasCopied = true; } data[attr] = associatedData[attr]; } } } return data; }, collectData: function(records, startIndex) { var data = [], i = 0, len = records.length, record; for (; i < len; i++) { record = records[i]; data[i] = this.prepareData(record.data, startIndex + i, record); } return data; }, bufferRender: function(records, index) { var me = this, div = me.renderBuffer, result = document.createDocumentFragment(), nodes, len, i; me.tpl.overwrite(div, me.collectData(records, index)); nodes = Ext.fly(div).query(me.getItemSelector()); for (i = 0 , len = nodes.length; i < len; i++) { result.appendChild(nodes[i]); } return { fragment: result, children: nodes }; }, nodeContainerSelector: null, getNodeContainer: function() { var target = this.getTargetEl(), selector = this.nodeContainerSelector; return selector ? target.down(selector, true) : target; }, getNodeContainerSelector: function() { return this.nodeContainerSelector; }, onUpdate: function(store, record, operation, modifiedFieldNames, details) { var me = this, isFiltered = details && details.filtered; if (!isFiltered && me.getNode(record)) { if (me.throttledUpdate) { me.statics().queueRecordChange(me, store, record, operation, modifiedFieldNames); } else { me.handleUpdate.apply(me, arguments); } } }, handleUpdate: function(store, record) { var me = this, index, node, selModel = me.getSelectionModel(); if (me.viewReady) { index = me.dataSource.indexOf(record); if (index > -1) { if (me.getNode(record)) { node = me.bufferRender([ record ], index).children[0]; me.all.replaceElement(index, node, true); me.updateIndexes(index, index); selModel.onUpdate(record); me.refreshSizePending = true; if (selModel.isSelected(record)) { me.onItemSelect(record); } if (me.hasListeners.itemupdate) { me.fireEvent('itemupdate', record, index, node); } return node; } } } }, onReplace: function(store, startIndex, oldRecords, newRecords) { var me = this, endIndex, all = me.all, selModel = me.getSelectionModel(), result, item, i, j, fragment, children; if (me.rendered) { result = me.bufferRender(newRecords, startIndex, true); fragment = result.fragment; children = result.children; item = all.item(startIndex); if (item) { all.item(startIndex).insertSibling(fragment, 'before', true); } else { me.appendNodes(fragment); } all.insert(startIndex, children); startIndex += newRecords.length; endIndex = startIndex + oldRecords.length - 1; all.removeRange(startIndex, endIndex, true); if (me.refreshSelmodelOnRefresh !== false) { selModel.refresh(); } me.updateIndexes(startIndex); if (me.hasListeners.itemremove) { for (i = oldRecords.length , j = endIndex; i >= 0; --i , --j) { me.fireEvent('itemremove', oldRecords[i], j, me); } } if (me.hasListeners.itemadd) { me.fireEvent('itemadd', newRecords, startIndex, children); } me.refreshSize(); } }, onAdd: function(store, records, index) { var me = this, nodes, selModel = me.getSelectionModel(); if (me.rendered) { if (me.all.getCount() === 0) { me.refresh(); nodes = me.all.slice(); } else { nodes = me.doAdd(records, index); if (me.refreshSelmodelOnRefresh !== false) { selModel.refresh(); } me.updateIndexes(index); me.refreshSizePending = true; } if (me.hasListeners.itemadd) { me.fireEvent('itemadd', records, index, nodes); } } }, appendNodes: function(nodes) { var all = this.all, count = all.getCount(); if (this.nodeContainerSelector) { this.getNodeContainer().appendChild(nodes); } else { all.item(count - 1).insertSibling(nodes, 'after'); } }, doAdd: function(records, index) { var me = this, result = me.bufferRender(records, index, true), fragment = result.fragment, children = result.children, all = me.all, count = all.getCount(), firstRowIndex = all.startIndex || 0, lastRowIndex = all.endIndex || count - 1; if (count === 0 || index > lastRowIndex) { me.appendNodes(fragment); } else if (index <= firstRowIndex) { all.item(firstRowIndex).insertSibling(fragment, 'before', true); } else { all.item(index).insertSibling(children, 'before', true); } all.insert(index, children); return children; }, onRemove: function(ds, records, index) { var me = this, rows = me.all, fireItemRemove = me.hasListeners.itemremove, currIdx, i, record, nodes, node; if (rows.getCount()) { if (me.dataSource.getCount() === 0) { if (fireItemRemove) { me.fireEvent('itemremove', records, index, me.getNodes(index, index + records.length - 1)); } me.refresh(); } else { if (fireItemRemove) { nodes = []; } for (i = records.length - 1; i >= 0; --i) { record = records[i]; currIdx = index + i; if (nodes) { node = rows.item(currIdx); nodes[i] = node ? node.dom : undefined; } if (rows.item(currIdx)) { me.doRemove(record, currIdx); } } if (fireItemRemove) { me.fireEvent('itemremove', records, index, nodes, me); } me.updateIndexes(index); } me.refreshSizePending = true; } }, doRemove: function(record, index) { this.all.removeElement(index, true); }, refreshNode: function(record) { if (Ext.isNumber(record)) { record = this.store.getAt(record); } this.onUpdate(this.dataSource, record); }, updateIndexes: function(startIndex, endIndex) { var nodes = this.all.elements, node, records = this.getViewRange(), i, myId = this.id; startIndex = startIndex || 0; endIndex = endIndex || ((endIndex === 0) ? 0 : (nodes.length - 1)); for (i = startIndex; i <= endIndex; i++) { node = nodes[i]; node.setAttribute('data-recordIndex', i); node.setAttribute('data-recordId', records[i].internalId); node.setAttribute('data-boundView', myId); } }, bindStore: function(store, initial, propName) { var me = this, selModel = me.getSelectionModel(); selModel.preventRefresh = true; selModel.bindStore(store); selModel.bindComponent(store ? me : null); selModel.preventRefresh = false; me.mixins.storeholder.bindStore.apply(me, arguments); if (store && me.componentLayoutCounter && !me.preventRefresh) { me.doFirstRefresh(store, !initial); } }, doFirstRefresh: function(store, noDefer) { var me = this; if (me.deferInitialRefresh && !noDefer) { Ext.defer(me.doFirstRefresh, 1, me, [ store, true ]); } else { if (store && !store.isLoading()) { me.refresh(); } } }, onUnbindStore: function(store, initial, propertyName) { if (propertyName === 'store') { this.setMaskBind(null); this.getSelectionModel().bindStore(null); } }, onBindStore: function(store, initial, propName) { var me = this; me.setMaskBind(store); if (!initial && propName === 'store') { me.preventRefresh = true; me.store = store; me.bindStore(store, false, 'dataSource'); me.preventRefresh = false; } }, setMaskBind: function(store) { var mask = this.loadMask; if (this.rendered && mask && store && !mask.bindStore) { mask = this.createMask(); } if (mask && mask.bindStore) { mask.bindStore(store); } }, getStoreListeners: function() { var me = this; return { refresh: me.onDataRefresh, replace: me.onReplace, add: me.onAdd, remove: me.onRemove, update: me.onUpdate, clear: me.refresh, beginupdate: me.onBeginUpdate, endupdate: me.onEndUpdate }; }, onBeginUpdate: function() { ++this.updateSuspendCounter; Ext.suspendLayouts(); }, onEndUpdate: function() { var me = this; if (me.updateSuspendCounter) { --me.updateSuspendCounter; } Ext.resumeLayouts(true); if (me.refreshSizePending) { me.refreshSize(true); me.refreshSizePending = false; } }, onDataRefresh: function() { this.refreshView(); }, refreshView: function() { var me = this, blocked = me.blockRefresh || !me.rendered || me.up('[collapsed],[isCollapsingOrExpanding],[hidden]'); if (blocked) { me.refreshNeeded = true; } else { if (me.bufferedRenderer && me.all.getCount()) { me.bufferedRenderer.refreshView(); } else { me.refresh(); } } }, findItemByChild: function(node) { return Ext.fly(node).findParent(this.getItemSelector(), this.getTargetEl()); }, findTargetByEvent: function(e) { return e.getTarget(this.getItemSelector(), this.getTargetEl()); }, getSelectedNodes: function() { var nodes = [], records = this.getSelectionModel().getSelection(), ln = records.length, i = 0; for (; i < ln; i++) { nodes.push(this.getNode(records[i])); } return nodes; }, getRecords: function(nodes) { var records = [], i = 0, len = nodes.length, data = this.dataSource.data; for (; i < len; i++) { records[records.length] = data.getByKey(nodes[i].getAttribute('data-recordId')); } return records; }, getRecord: function(node) { return this.dataSource.getByInternalId(Ext.getDom(node).getAttribute('data-recordId')); }, isSelected: function(node) { var r = this.getRecord(node); return this.getSelectionModel().isSelected(r); }, select: function(records, keepExisting, suppressEvent) { this.getSelectionModel().select(records, keepExisting, suppressEvent); }, deselect: function(records, suppressEvent) { this.getSelectionModel().deselect(records, suppressEvent); }, getNode: function(nodeInfo) { var me = this, out; if (me.rendered && (nodeInfo || nodeInfo === 0)) { if (Ext.isString(nodeInfo)) { out = document.getElementById(nodeInfo); } else if (nodeInfo.isModel) { out = me.getNodeByRecord(nodeInfo); } else if (Ext.isNumber(nodeInfo)) { out = me.all.elements[nodeInfo]; } else { if (nodeInfo.target) { nodeInfo = nodeInfo.target; } out = Ext.fly(nodeInfo).findParent(me.itemSelector, me.getTargetEl()); } } return out || null; }, getNodeByRecord: function(record) { var index = this.store.indexOf(record); return this.all.elements[index] || null; }, getNodes: function(start, end) { var all = this.all; if (end !== undefined) { end++; } return all.slice(start, end); }, indexOf: function(node) { node = this.getNode(node); if (!node && node !== 0) { return -1; } if (node.getAttribute('data-recordIndex')) { return Number(node.getAttribute('data-recordIndex')); } return this.all.indexOf(node); }, onDestroy: function() { var me = this, count = me.updateSuspendCounter; me.all.clear(); me.emptyEl = null; me.callParent(); me.bindStore(null); Ext.destroy(me.navigationModel, me.selectionModel); while (count--) { Ext.resumeLayouts(true); } }, onItemSelect: function(record) { var node = this.getNode(record); if (node) { Ext.fly(node).addCls(this.selectedItemCls); } }, onItemDeselect: function(record) { var node = this.getNode(record); if (node) { Ext.fly(node).removeCls(this.selectedItemCls); } }, getItemSelector: function() { return this.itemSelector; }, addItemCls: function(itemInfo, cls) { var item = this.getNode(itemInfo); if (item) { Ext.fly(item).addCls(cls); } }, removeItemCls: function(itemInfo, cls) { var item = this.getNode(itemInfo); if (item) { Ext.fly(item).removeCls(cls); } }, updateStore: function(store) { if (!this.isConfiguring) { delete this.store; this.bindStore(store); } }, privates: { createMask: function(mask) { var me = this, maskStore = me.getStore(), cfg; if (maskStore && !maskStore.isEmptyStore && !maskStore.loadsSynchronously()) { cfg = { target: me, msg: me.loadingText, useMsg: me.loadingUseMsg, store: maskStore }; if (me.loadingCls) { cfg.msgCls = me.loadingCls; } if (Ext.isObject(mask)) { cfg = Ext.apply(cfg, mask); } me.loadMask = new Ext.LoadMask(cfg); me.loadMask.on({ scope: me, beforeshow: me.onMaskBeforeShow, hide: me.onMaskHide }); } return me.loadMask; }, getFocusEl: function() { return this.el; }, getOverflowEl: function() { return Ext.Component.prototype.getTargetEl.call(this); }, getTargetEl: function() { return this.touchScroll ? this.getScrollerEl() : this.callParent(); } } }, function() { Ext.deprecate('extjs', '4.0', function() { Ext.view.AbstractView.override({ getSelectionCount: function() { if (Ext.global.console) { Ext.global.console.warn("DataView: getSelectionCount will be removed, please interact with the Ext.selection.DataViewModel"); } return this.selModel.getSelection().length; }, getSelectedRecords: function() { if (Ext.global.console) { Ext.global.console.warn("DataView: getSelectedRecords will be removed, please interact with the Ext.selection.DataViewModel"); } return this.selModel.getSelection(); }, select: function(records, keepExisting, supressEvents) { if (Ext.global.console) { Ext.global.console.warn("DataView: select will be removed, please access select through a DataView's SelectionModel, ie: view.getSelectionModel().select()"); } var sm = this.getSelectionModel(); return sm.select.apply(sm, arguments); }, clearSelections: function() { if (Ext.global.console) { Ext.global.console.warn("DataView: clearSelections will be removed, please access deselectAll through DataView's SelectionModel, ie: view.getSelectionModel().deselectAll()"); } var sm = this.getSelectionModel(); return sm.deselectAll(); } }); }); }); Ext.define('Ext.view.View', { extend: 'Ext.view.AbstractView', alternateClassName: 'Ext.DataView', alias: 'widget.dataview', inputTagRe: /^textarea$|^input$/i, keyEventRe: /^key/, inheritableStatics: { EventMap: { longpress: 'LongPress', mousedown: 'MouseDown', mouseup: 'MouseUp', click: 'Click', dblclick: 'DblClick', contextmenu: 'ContextMenu', mouseover: 'MouseOver', mouseout: 'MouseOut', mouseenter: 'MouseEnter', mouseleave: 'MouseLeave', keydown: 'KeyDown', keyup: 'KeyUp', keypress: 'KeyPress', focus: 'Focus' }, TouchEventMap: { touchstart: 'mousedown', touchend: 'mouseup', tap: 'click', doubletap: 'dblclick' } }, afterRender: function() { var me = this; me.callParent(); me.mon(me.el, { scope: me, click: me.handleEvent, longpress: me.handleEvent, mousedown: me.handleEvent, mouseup: me.handleEvent, dblclick: me.handleEvent, contextmenu: me.handleEvent, keydown: me.handleEvent, keyup: me.handleEvent, keypress: me.handleEvent, mouseover: me.handleMouseOver, mouseout: me.handleMouseOut }); }, getTargetSelector: function() { return this.dataRowSelector || this.itemSelector; }, handleMouseOver: function(e) { var me = this, itemSelector = me.getTargetSelector(), item = e.getTarget(itemSelector); if (!me.isDestroyed) { if (item) { if (me.mouseOverItem !== item && me.el.contains(item)) { me.mouseOverItem = e.item = item; e.newType = 'mouseenter'; me.handleEvent(e); } } else { me.handleEvent(e); } } }, handleMouseOut: function(e) { var itemSelector = this.getTargetSelector(), item = e.getTarget(itemSelector), computedRelatedTarget = e.getRelatedTarget(itemSelector), sourceView; if ((item === computedRelatedTarget) && !(item === null && computedRelatedTarget === null)) { return; } if (!this.isDestroyed) { if (item && (sourceView = this.self.getBoundView(item))) { e.item = item; e.newType = 'mouseleave'; sourceView.handleEvent(e); sourceView.mouseOverItem = null; } else { this.handleEvent(e); } } }, handleEvent: function(e) { var me = this, isKeyEvent = me.keyEventRe.test(e.type), nm = me.getNavigationModel(); e.view = me; if (isKeyEvent) { e.item = nm.getItem(); e.record = nm.getRecord(); } if (!e.item) { e.item = e.getTarget(me.itemSelector); } if (e.item && !e.record) { e.record = me.getRecord(e.item); } if (me.processUIEvent(e) !== false) { me.processSpecialEvent(e); } if (isKeyEvent && !Ext.fly(e.target).isInputField()) { if (e.getKey() === e.SPACE || e.isNavKeyPress(true)) { e.preventDefault(); } } }, processItemEvent: Ext.emptyFn, processContainerEvent: Ext.emptyFn, processSpecialEvent: Ext.emptyFn, processUIEvent: function(e) { if (!Ext.getBody().isAncestor(e.target)) { return; } var me = this, item = e.item, self = me.self, map = self.EventMap, touchMap = self.TouchEventMap, index, record = e.record, type = e.type, newType = type; if (e.newType) { newType = e.newType; } if (item) { newType = touchMap[newType] || newType; index = e.recordIndex = me.indexInStore ? me.indexInStore(record) : me.indexOf(item); if (!record || me.processItemEvent(record, item, index, e) === false) { return false; } if ((me['onBeforeItem' + map[newType]](record, item, index, e) === false) || (me.fireEvent('beforeitem' + newType, me, record, item, index, e) === false) || (me['onItem' + map[newType]](record, item, index, e) === false)) { return false; } me.fireEvent('item' + newType, me, record, item, index, e); } else { type = touchMap[type] || type; if ((me.processContainerEvent(e) === false) || (me['onBeforeContainer' + map[type]](e) === false) || (me.fireEvent('beforecontainer' + type, me, e) === false) || (me['onContainer' + map[type]](e) === false)) { return false; } me.fireEvent('container' + type, me, e); } return true; }, onItemMouseEnter: function(record, item, index, e) { if (this.trackOver) { this.highlightItem(item); } }, onItemMouseLeave: function(record, item, index, e) { if (this.trackOver) { this.clearHighlight(); } }, onItemMouseDown: Ext.emptyFn, onItemLongPress: Ext.emptyFn, onItemMouseUp: Ext.emptyFn, onItemFocus: Ext.emptyFn, onItemClick: Ext.emptyFn, onItemDblClick: Ext.emptyFn, onItemContextMenu: Ext.emptyFn, onItemKeyDown: Ext.emptyFn, onItemKeyUp: Ext.emptyFn, onItemKeyPress: Ext.emptyFn, onBeforeItemLongPress: Ext.emptyFn, onBeforeItemMouseDown: Ext.emptyFn, onBeforeItemMouseUp: Ext.emptyFn, onBeforeItemFocus: Ext.emptyFn, onBeforeItemMouseEnter: Ext.emptyFn, onBeforeItemMouseLeave: Ext.emptyFn, onBeforeItemClick: Ext.emptyFn, onBeforeItemDblClick: Ext.emptyFn, onBeforeItemContextMenu: Ext.emptyFn, onBeforeItemKeyDown: Ext.emptyFn, onBeforeItemKeyUp: Ext.emptyFn, onBeforeItemKeyPress: Ext.emptyFn, onContainerMouseDown: Ext.emptyFn, onContainerLongPress: Ext.emptyFn, onContainerMouseUp: Ext.emptyFn, onContainerMouseOver: Ext.emptyFn, onContainerMouseOut: Ext.emptyFn, onContainerClick: Ext.emptyFn, onContainerDblClick: Ext.emptyFn, onContainerContextMenu: Ext.emptyFn, onContainerKeyDown: Ext.emptyFn, onContainerKeyUp: Ext.emptyFn, onContainerKeyPress: Ext.emptyFn, onBeforeContainerMouseDown: Ext.emptyFn, onBeforeContainerLongPress: Ext.emptyFn, onBeforeContainerMouseUp: Ext.emptyFn, onBeforeContainerMouseOver: Ext.emptyFn, onBeforeContainerMouseOut: Ext.emptyFn, onBeforeContainerClick: Ext.emptyFn, onBeforeContainerDblClick: Ext.emptyFn, onBeforeContainerContextMenu: Ext.emptyFn, onBeforeContainerKeyDown: Ext.emptyFn, onBeforeContainerKeyUp: Ext.emptyFn, onBeforeContainerKeyPress: Ext.emptyFn, setHighlightedItem: function(item) { var me = this, highlighted = me.highlightedItem, overItemCls = me.overItemCls; if (highlighted !== item) { if (highlighted) { Ext.fly(highlighted).removeCls(overItemCls); if (Ext.isIE8) { me.repaintBorder(highlighted); me.repaintBorder(highlighted.nextSibling); } if (me.hasListeners.unhighlightitem) { me.fireEvent('unhighlightitem', me, highlighted); } } me.highlightedItem = item; if (item) { Ext.fly(item).addCls(me.overItemCls); if (Ext.isIE8) { me.repaintBorder(item.nextSibling); } if (me.hasListeners.highlightitem) { me.fireEvent('highlightitem', me, item); } } } }, highlightItem: function(item) { this.setHighlightedItem(item); }, clearHighlight: function() { this.setHighlightedItem(undefined); }, handleUpdate: function(store, record) { var me = this, node, newNode, highlighted; if (me.viewReady) { node = me.getNode(record); newNode = me.callParent(arguments); highlighted = me.highlightedItem; if (highlighted && highlighted === node) { delete me.highlightedItem; if (newNode) { me.highlightItem(newNode); } } } }, refresh: function() { this.clearHighlight(); this.callParent(arguments); }, focusNode: function(rec) { var me = this, node = me.getNode(rec), el = me.el, adjustmentY = 0, adjustmentX = 0, elRegion = el.getRegion(), nodeRegion; elRegion.bottom = elRegion.top + el.dom.clientHeight; elRegion.right = elRegion.left + el.dom.clientWidth; if (node) { nodeRegion = Ext.fly(node).getRegion(); if (nodeRegion.top < elRegion.top) { adjustmentY = nodeRegion.top - elRegion.top; } else if (nodeRegion.bottom > elRegion.bottom) { adjustmentY = nodeRegion.bottom - elRegion.bottom; } if (nodeRegion.left < elRegion.left) { adjustmentX = nodeRegion.left - elRegion.left; } else if (nodeRegion.right > elRegion.right) { adjustmentX = nodeRegion.right - elRegion.right; } if (adjustmentX || adjustmentY) { me.scrollBy(adjustmentX, adjustmentY, false); } Ext.fly(node).set({ tabIndex: -1 }); node.focus(); } }, bindStore: function(store, initial, propertyName) { var me = this, dataSource = me[propertyName], selModel = me.getSelectionModel(); if (dataSource && dataSource.isFeatureStore && me.rendered) { selModel.bindStore(dataSource.store); selModel.bindComponent(me); if (store.isFeatureStore) { me.bindStoreListeners(store); dataSource.bindStore(dataSource.store); } else { dataSource.bindStore(store); } } else { me.callParent([ store, initial, propertyName ]); } }, privates: { repaintBorder: function(rowIdx) { var node = this.getNode(rowIdx); if (node) { node.className = node.className; } } } }); Ext.define('Ext.grid.CellContext', { isCellContext: true, constructor: function(view) { this.view = view; }, isEqual: function(other) { if (other) { return this.record === other.record && this.column === other.column; } return false; }, setPosition: function(row, col) { var me = this; if (arguments.length === 1) { if (row.length) { col = row[0]; col = row[1]; } else { if (row.view) { me.view = row.view; } col = row.column; row = row.row; } } me.setRow(row); me.setColumn(col); return me; }, setAll: function(view, recordIndex, columnIndex, record, columnHeader) { var me = this; me.view = view; me.rowIdx = recordIndex; me.colIdx = columnIndex; me.record = record; me.column = columnHeader; return me; }, setRow: function(row) { var me = this, dataSource = me.view.dataSource; if (row !== undefined) { if (typeof row === 'number') { me.rowIdx = Math.max(Math.min(row, dataSource.getCount() - 1), 0); me.record = dataSource.getAt(row); } else if (row.isModel) { me.record = row; me.rowIdx = dataSource.indexOf(row); } else if (row.tagName) { me.record = me.view.getRecord(row); me.rowIdx = dataSource.indexOf(me.record); } } }, setColumn: function(col) { var me = this, colMgr = me.view.getVisibleColumnManager(); if (col !== undefined) { if (typeof col === 'number') { me.colIdx = col; me.column = colMgr.getHeaderAtIndex(col); } else if (col.isHeader) { me.column = col; me.colIdx = colMgr.indexOf(col); } } }, next: function() { var me = this, mgr = me.view.getVisibleColumnManager(); me.colIdx++; if (me.colIdx === mgr.getColumns().length) { me.setPosition(Math.min(me.rowIdx + 1, me.view.dataSource.getCount() - 1), me.colIdx); } else { me.setColumn(me.colIdx); } }, equal: function(other) { return (other && other.isCellContext && other.view === this.view && other.record === this.record && other.column === this.column); }, clone: function() { var me = this, result = new me.self(me.view); result.rowIdx = me.rowIdx; result.colIdx = me.colIdx; result.record = me.record; result.column = me.column; return result; } }); Ext.define('Ext.view.TableLayout', { extend: 'Ext.layout.component.Auto', alias: 'layout.tableview', type: 'tableview', beginLayout: function(ownerContext) { var me = this, partner = me.owner.lockingPartner, context = ownerContext.context; if (!me.columnFlusherId) { me.columnFlusherId = me.id + '-columns'; me.rowHeightFlusherId = me.id + '-rows'; } me.callParent([ ownerContext ]); if (partner && partner.grid.isVisible()) { if (!ownerContext.lockingPartnerContext) { (ownerContext.lockingPartnerContext = context.getCmp(partner)).lockingPartnerContext = ownerContext; } ownerContext.rowHeightSynchronizer = me.owner.syncRowHeightBegin(); } (ownerContext.headerContext = context.getCmp(me.headerCt)).viewContext = ownerContext; }, beginLayoutCycle: function(ownerContext, firstCycle) { this.callParent([ ownerContext, firstCycle ]); if (ownerContext.syncRowHeights) { ownerContext.target.syncRowHeightClear(ownerContext.rowHeightSynchronizer); ownerContext.syncRowHeights = false; } }, calculate: function(ownerContext) { var me = this, context = ownerContext.context, lockingPartnerContext = ownerContext.lockingPartnerContext, headerContext = ownerContext.headerContext, ownerCtContext = ownerContext.ownerCtContext, owner = me.owner, columnsChanged = headerContext.getProp('columnsChanged'), state = ownerContext.state, columnFlusher, otherSynchronizer, synchronizer, rowHeightFlusher, bodyDom = owner.body.dom, bodyHeight, ctSize, overflowY; if (!owner.all.getCount() && (!bodyDom || !owner.body.child('table'))) { ownerContext.setProp('viewOverflowY', false); me.callParent([ ownerContext ]); return; } if (columnsChanged === undefined) { me.done = false; return; } if (columnsChanged) { if (!(columnFlusher = state.columnFlusher)) { context.queueFlush(state.columnFlusher = columnFlusher = { ownerContext: ownerContext, columnsChanged: columnsChanged, layout: me, id: me.columnFlusherId, flush: me.flushColumnWidths }); } if (!columnFlusher.flushed) { me.done = false; return; } } if (lockingPartnerContext) { if (!(rowHeightFlusher = state.rowHeightFlusher)) { if (!(synchronizer = state.rowHeights)) { state.rowHeights = synchronizer = ownerContext.rowHeightSynchronizer; me.owner.syncRowHeightMeasure(synchronizer); ownerContext.setProp('rowHeights', synchronizer); } if (!(otherSynchronizer = lockingPartnerContext.getProp('rowHeights'))) { me.done = false; return; } context.queueFlush(state.rowHeightFlusher = rowHeightFlusher = { ownerContext: ownerContext, synchronizer: synchronizer, otherSynchronizer: otherSynchronizer, layout: me, id: me.rowHeightFlusherId, flush: me.flushRowHeights }); } if (!rowHeightFlusher.flushed) { me.done = false; return; } } me.callParent([ ownerContext ]); if (!ownerContext.heightModel.shrinkWrap) { overflowY = false; if (!ownerCtContext.heightModel.shrinkWrap) { ctSize = ownerCtContext.target.layout.getContainerSize(ownerCtContext); if (!ctSize.gotHeight) { me.done = false; return; } bodyHeight = bodyDom.offsetHeight; overflowY = bodyHeight > ctSize.height; } ownerContext.setProp('viewOverflowY', overflowY); } }, measureContentHeight: function(ownerContext) { var owner = this.owner, bodyDom = owner.body.dom, emptyEl = owner.emptyEl, bodyHeight = 0; if (emptyEl) { bodyHeight += emptyEl.offsetHeight; } if (bodyDom) { bodyHeight += bodyDom.offsetHeight; } if (ownerContext.headerContext.state.boxPlan.tooNarrow) { bodyHeight += Ext.getScrollbarSize().height; } return bodyHeight; }, flushColumnWidths: function() { var flusher = this, me = flusher.layout, ownerContext = flusher.ownerContext, columnsChanged = flusher.columnsChanged, owner = ownerContext.target, len = columnsChanged.length, column, i, colWidth, lastBox; if (ownerContext.state.columnFlusher !== flusher) { return; } for (i = 0; i < len; i++) { if (!(column = columnsChanged[i])) { continue; } colWidth = column.props.width; owner.body.select(owner.getColumnSizerSelector(column.target)).setWidth(colWidth); lastBox = column.lastBox; if (lastBox) { lastBox.width = colWidth; } } flusher.flushed = true; if (!me.pending) { ownerContext.context.queueLayout(me); } }, flushRowHeights: function() { var flusher = this, me = flusher.layout, ownerContext = flusher.ownerContext; if (ownerContext.state.rowHeightFlusher !== flusher) { return; } ownerContext.target.syncRowHeightFinish(flusher.synchronizer, flusher.otherSynchronizer); flusher.flushed = true; ownerContext.syncRowHeights = true; if (!me.pending) { ownerContext.context.queueLayout(me); } }, finishedLayout: function(ownerContext) { var nodeContainer = Ext.fly(this.owner.getNodeContainer()); this.callParent([ ownerContext ]); if (nodeContainer) { nodeContainer.setWidth(ownerContext.headerContext.props.contentWidth); } } }); Ext.define('Ext.grid.locking.RowSynchronizer', { constructor: function(view, rowEl) { var me = this, rowTpl; me.view = view; me.rowEl = rowEl; me.els = {}; me.add('data', view.rowSelector); for (rowTpl = view.rowTpl; rowTpl; rowTpl = rowTpl.nextTpl) { if (rowTpl.beginRowSync) { rowTpl.beginRowSync(me); } } }, add: function(name, selector) { var el = Ext.fly(this.rowEl).down(selector, true); if (el) { this.els[name] = { el: el }; } }, finish: function(other) { var me = this, els = me.els, otherEls = other.els, otherEl, growth = 0, otherGrowth = 0, delta, name, otherHeight; for (name in els) { otherEl = otherEls[name]; otherHeight = otherEl ? otherEl.height : 0; delta = otherHeight - els[name].height; if (delta > 0) { growth += delta; Ext.fly(els[name].el).setHeight(otherHeight); } else { otherGrowth -= delta; } } otherHeight = other.rowHeight + otherGrowth; if (me.rowHeight + growth < otherHeight) { Ext.fly(me.rowEl).setHeight(otherHeight); } }, measure: function() { var me = this, els = me.els, name; me.rowHeight = me.rowEl.offsetHeight; for (name in els) { els[name].height = els[name].el.offsetHeight; } }, reset: function() { var els = this.els, name; this.rowEl.style.height = ''; for (name in els) { els[name].el.style.height = ''; } } }); Ext.define('Ext.view.NodeCache', { requires: [ 'Ext.dom.CompositeElementLite' ], statics: { range: document.createRange && document.createRange() }, constructor: function(view) { this.view = view; this.clear(); this.el = new Ext.dom.Fly(); }, clear: function(removeDom) { var me = this, elements = me.elements, range = me.statics().range, key; if (me.count && removeDom) { if (range) { range.setStartBefore(elements[me.startIndex]); range.setEndAfter(elements[me.endIndex]); range.deleteContents(); } else { for (key in elements) { Ext.removeNode(elements[key]); } } } me.elements = {}; me.count = me.startIndex = 0; me.endIndex = -1; }, fill: function(newElements, startIndex, fixedNodes) { fixedNodes = fixedNodes || 0; var me = this, elements = me.elements = {}, i, len = newElements.length - fixedNodes; if (!startIndex) { startIndex = 0; } for (i = 0; i < len; i++) { elements[startIndex + i] = newElements[i + fixedNodes]; } me.startIndex = startIndex; me.endIndex = startIndex + len - 1; me.count = len; return this; }, insert: function(insertPoint, nodes) { var me = this, elements = me.elements, i, nodeCount = nodes.length; if (me.count) { if (insertPoint > me.endIndex + 1 || insertPoint + nodes.length - 1 < me.startIndex) { Ext.Error.raise('Discontiguous range would result from inserting ' + nodes.length + ' nodes at ' + insertPoint); } if (insertPoint < me.count) { for (i = me.endIndex + nodeCount; i >= insertPoint + nodeCount; i--) { elements[i] = elements[i - nodeCount]; elements[i].setAttribute('data-recordIndex', i); } } me.endIndex = me.endIndex + nodeCount; } else { me.startIndex = insertPoint; me.endIndex = insertPoint + nodeCount - 1; } for (i = 0; i < nodeCount; i++ , insertPoint++) { elements[insertPoint] = nodes[i]; elements[insertPoint].setAttribute('data-recordIndex', insertPoint); } me.count += nodeCount; }, invoke: function(fn, args) { var me = this, element, i; fn = Ext.dom.Element.prototype[fn]; for (i = me.startIndex; i <= me.endIndex; i++) { element = me.item(i); if (element) { fn.apply(element, args); } } return me; }, item: function(index, asDom) { var el = this.elements[index], result = null; if (el) { result = asDom ? this.elements[index] : this.el.attach(this.elements[index]); } return result; }, first: function(asDom) { return this.item(this.startIndex, asDom); }, last: function(asDom) { return this.item(this.endIndex, asDom); }, moveBlock: function(increment) { var me = this, elements = me.elements, node, end, step, i; if (increment < 0) { i = me.startIndex - 1; end = me.endIndex; step = 1; } else { i = me.endIndex + 1; end = me.startIndex; step = -1; } me.startIndex += increment; me.endIndex += increment; do { i += step; node = elements[i + increment] = elements[i]; node.setAttribute('data-recordIndex', i + increment); if (i < me.startIndex || i > me.endIndex) { delete elements[i]; } } while ( i !== end); delete elements[i]; }, getCount: function() { return this.count; }, slice: function(start, end) { var elements = this.elements, result = [], i; if (!end) { end = this.endIndex; } else { end = Math.min(this.endIndex, end - 1); } for (i = start || this.startIndex; i <= end; i++) { result.push(elements[i]); } return result; }, replaceElement: function(el, replacement, domReplace) { var elements = this.elements, index = (typeof el === 'number') ? el : this.indexOf(el); if (index > -1) { replacement = Ext.getDom(replacement); if (domReplace) { el = elements[index]; el.parentNode.insertBefore(replacement, el); Ext.removeNode(el); replacement.setAttribute('data-recordIndex', index); } this.elements[index] = replacement; } return this; }, indexOf: function(el) { var elements = this.elements, index; el = Ext.getDom(el); for (index = this.startIndex; index <= this.endIndex; index++) { if (elements[index] === el) { return index; } } return -1; }, removeRange: function(start, end, removeDom) { var me = this, elements = me.elements, el, i, removeCount, fromPos; if (end == null) { end = me.endIndex + 1; } else { end = Math.min(me.endIndex + 1, end + 1); } if (start == null) { start = me.startIndex; } removeCount = end - start; for (i = start , fromPos = end; i <= me.endIndex; i++ , fromPos++) { el = elements[i]; if (removeDom && i < end) { Ext.removeNode(el); } if (fromPos <= me.endIndex) { el = elements[i] = elements[fromPos]; el.setAttribute('data-recordIndex', i); } else { delete elements[i]; } } me.count -= removeCount; me.endIndex -= removeCount; }, removeElement: function(keys, removeDom) { var me = this, inKeys, key, elements = me.elements, el, deleteCount, keyIndex = 0, index, fromIndex; if (Ext.isArray(keys)) { inKeys = keys; keys = []; deleteCount = inKeys.length; for (keyIndex = 0; keyIndex < deleteCount; keyIndex++) { key = inKeys[keyIndex]; if (typeof key !== 'number') { key = me.indexOf(key); } if (key >= me.startIndex && key <= me.endIndex) { keys[keys.length] = key; } } Ext.Array.sort(keys); deleteCount = keys.length; } else { if (keys < me.startIndex || keys > me.endIndex) { return; } deleteCount = 1; keys = [ keys ]; } for (index = fromIndex = keys[0] , keyIndex = 0; index <= me.endIndex; index++ , fromIndex++) { if (keyIndex < deleteCount && index === keys[keyIndex]) { fromIndex++; keyIndex++; if (removeDom) { Ext.removeNode(elements[index]); } } if (fromIndex <= me.endIndex && fromIndex >= me.startIndex) { el = elements[index] = elements[fromIndex]; el.setAttribute('data-recordIndex', index); } else { delete elements[index]; } } me.endIndex -= deleteCount; me.count -= deleteCount; }, scroll: function(newRecords, direction, removeCount) { var me = this, view = me.view, store = view.store, elements = me.elements, recCount = newRecords.length, nodeContainer = view.getNodeContainer(), fireItemRemove = view.hasListeners.itemremove, fireItemAdd = view.hasListeners.itemadd, range = me.statics().range, i, el, removeEnd, children, result; if (!newRecords.length) { return; } if (direction === -1) { if (removeCount) { if (range) { range.setStartBefore(elements[(me.endIndex - removeCount) + 1]); range.setEndAfter(elements[me.endIndex]); range.deleteContents(); for (i = (me.endIndex - removeCount) + 1; i <= me.endIndex; i++) { el = elements[i]; delete elements[i]; if (fireItemRemove) { view.fireEvent('itemremove', store.getByInternalId(el.getAttribute('data-recordId')), i, el, view); } } } else { for (i = (me.endIndex - removeCount) + 1; i <= me.endIndex; i++) { el = elements[i]; delete elements[i]; Ext.removeNode(el); if (fireItemRemove) { view.fireEvent('itemremove', store.getByInternalId(el.getAttribute('data-recordId')), i, el, view); } } } me.endIndex -= removeCount; } if (newRecords.length) { result = view.bufferRender(newRecords, me.startIndex -= recCount); children = result.children; for (i = 0; i < recCount; i++) { elements[me.startIndex + i] = children[i]; } nodeContainer.insertBefore(result.fragment, nodeContainer.firstChild); if (fireItemAdd) { view.fireEvent('itemadd', newRecords, me.startIndex, children); } } } else { if (removeCount) { removeEnd = me.startIndex + removeCount; if (range) { range.setStartBefore(elements[me.startIndex]); range.setEndAfter(elements[removeEnd - 1]); range.deleteContents(); for (i = me.startIndex; i < removeEnd; i++) { el = elements[i]; delete elements[i]; if (fireItemRemove) { view.fireEvent('itemremove', store.getByInternalId(el.getAttribute('data-recordId')), i, el, view); } } } else { for (i = me.startIndex; i < removeEnd; i++) { el = elements[i]; delete elements[i]; Ext.removeNode(el); if (fireItemRemove) { view.fireEvent('itemremove', store.getByInternalId(el.getAttribute('data-recordId')), i, el, view); } } } me.startIndex = removeEnd; } result = view.bufferRender(newRecords, me.endIndex + 1); children = result.children; for (i = 0; i < recCount; i++) { elements[me.endIndex += 1] = children[i]; } nodeContainer.appendChild(result.fragment); if (fireItemAdd) { view.fireEvent('itemadd', newRecords, me.endIndex + 1, children); } } me.count = me.endIndex - me.startIndex + 1; return children; }, sumHeights: function() { var result = 0, elements = this.elements, i; for (i = this.startIndex; i <= this.endIndex; i++) { result += elements[i].offsetHeight; } return result; } }, function() { Ext.dom.CompositeElementLite.importElementMethods.call(this); }); Ext.define('Ext.view.Table', { extend: 'Ext.view.View', xtype: [ 'tableview', 'gridview' ], alternateClassName: 'Ext.grid.View', requires: [ 'Ext.grid.CellContext', 'Ext.view.TableLayout', 'Ext.grid.locking.RowSynchronizer', 'Ext.view.NodeCache', 'Ext.util.DelayedTask', 'Ext.util.MixedCollection' ], isTableView: true, config: { selectionModel: { type: 'rowmodel' } }, inheritableStatics: { events: [ "blur", "focus", "move", "resize", "destroy", "beforedestroy", "boxready", "afterrender", "render", "beforerender", "removed", "hide", "beforehide", "show", "beforeshow", "enable", "disable", "added", "deactivate", "beforedeactivate", "activate", "beforeactivate", "cellkeydown", "beforecellkeydown", "cellmouseup", "beforecellmouseup", "cellmousedown", "beforecellmousedown", "cellcontextmenu", "beforecellcontextmenu", "celldblclick", "beforecelldblclick", "cellclick", "beforecellclick", "refresh", "itemremove", "itemadd", "itemupdate", "viewready", "beforerefresh", "unhighlightitem", "highlightitem", "focuschange", "deselect", "select", "beforedeselect", "beforeselect", "selectionchange", "containerkeydown", "containercontextmenu", "containerdblclick", "containerclick", "containermouseout", "containermouseover", "containermouseup", "containermousedown", "beforecontainerkeydown", "beforecontainercontextmenu", "beforecontainerdblclick", "beforecontainerclick", "beforecontainermouseout", "beforecontainermouseover", "beforecontainermouseup", "beforecontainermousedown", "itemkeydown", "itemcontextmenu", "itemdblclick", "itemclick", "itemmouseleave", "itemmouseenter", "itemmouseup", "itemmousedown", "rowclick", "rowcontextmenu", "rowdblclick", "rowkeydown", "rowmouseup", "rowmousedown", "rowkeydown", "beforeitemkeydown", "beforeitemcontextmenu", "beforeitemdblclick", "beforeitemclick", "beforeitemmouseleave", "beforeitemmouseenter", "beforeitemmouseup", "beforeitemmousedown", "statesave", "beforestatesave", "staterestore", "beforestaterestore", "uievent", "groupcollapse", "groupexpand" ] }, scrollable: true, componentLayout: 'tableview', baseCls: Ext.baseCSSPrefix + 'grid-view', unselectableCls: Ext.baseCSSPrefix + 'unselectable', firstCls: Ext.baseCSSPrefix + 'grid-cell-first', lastCls: Ext.baseCSSPrefix + 'grid-cell-last', itemCls: Ext.baseCSSPrefix + 'grid-item', selectedItemCls: Ext.baseCSSPrefix + 'grid-item-selected', selectedCellCls: Ext.baseCSSPrefix + 'grid-cell-selected', focusedItemCls: Ext.baseCSSPrefix + 'grid-item-focused', overItemCls: Ext.baseCSSPrefix + 'grid-item-over', altRowCls: Ext.baseCSSPrefix + 'grid-item-alt', dirtyCls: Ext.baseCSSPrefix + 'grid-dirty-cell', rowClsRe: new RegExp('(?:^|\\s*)' + Ext.baseCSSPrefix + 'grid-item-alt(?:\\s+|$)', 'g'), cellRe: new RegExp(Ext.baseCSSPrefix + 'grid-cell-([^\\s]+)(?:\\s|$)', ''), positionBody: true, positionCells: false, stripeOnUpdate: null, trackOver: true, getRowClass: null, stripeRows: true, markDirty: true, ariaRole: 'grid', tpl: [ '{%', 'view = values.view;', 'if (!(columns = values.columns)) {', 'columns = values.columns = view.ownerCt.getVisibleColumnManager().getColumns();', '}', 'values.fullWidth = 0;', 'for (i = 0, len = columns.length; i < len; i++) {', 'column = columns[i];', 'values.fullWidth += (column.cellWidth = column.lastBox ? column.lastBox.width : column.width || column.minWidth);', '}', 'tableCls=values.tableCls=[];', '%}', '
', '{[view.renderTHead(values, out, parent)]}', '{%', 'view.renderRows(values.rows, values.columns, values.viewStartIndex, out);', '%}', '{[view.renderTFoot(values, out, parent)]}', '
', { definitions: 'var view, tableCls, columns, i, len, column;', priority: 0 } ], outerRowTpl: [ '', '{%', 'this.nextTpl.applyOut(values, out, parent)', '%}', '
', { priority: 9999 } ], rowTpl: [ '{%', 'var dataRowCls = values.recordIndex === -1 ? "" : " ' + Ext.baseCSSPrefix + 'grid-row";', '%}', '', '' + '{%', 'parent.view.renderCell(values, parent.record, parent.recordIndex, parent.rowIndex, xindex - 1, out, parent)', '%}', '', '', { priority: 0 } ], cellTpl: [ '{tdStyle}" tabindex="-1" {ariaCellAttr} data-columnid="{[values.column.getItemId()]}">', '
{style}" {ariaCellInnerAttr}>{value}
', '', { priority: 0 } ], refreshSelmodelOnRefresh: false, tableValues: {}, rowValues: { itemClasses: [], rowClasses: [] }, cellValues: { classes: [ Ext.baseCSSPrefix + 'grid-cell ' + Ext.baseCSSPrefix + 'grid-td' ] }, constructor: function(config) { if (config.grid.isTree) { config.baseCls = Ext.baseCSSPrefix + 'tree-view'; } this.callParent([ config ]); }, hasVariableRowHeight: function(fromLockingPartner) { var me = this; return me.variableRowHeight || me.store.isGrouped() || me.getVisibleColumnManager().hasVariableRowHeight() || (!fromLockingPartner && me.lockingPartner && me.lockingPartner.hasVariableRowHeight(true)); }, initComponent: function() { var me = this; if (me.columnLines) { me.addCls(me.grid.colLinesCls); } if (me.rowLines) { me.addCls(me.grid.rowLinesCls); } me.body = new Ext.dom.Fly(); me.body.id = me.id + 'gridBody'; if (!me.trackOver) { me.overItemCls = null; } me.headerCt.view = me; me.grid.view = me; me.initFeatures(me.grid); me.itemSelector = me.getItemSelector(); me.all = new Ext.view.NodeCache(me); me.callParent(); }, applySelectionModel: function(selModel, oldSelModel) { var me = this, grid = me.ownerGrid, defaultType = selModel.type; if (!oldSelModel) { if (!(selModel && selModel.isSelectionModel)) { selModel = grid.selModel || selModel; } } if (selModel) { if (selModel.isSelectionModel) { selModel.allowDeselect = grid.allowDeselect || selModel.selectionMode !== 'SINGLE'; selModel.locked = grid.disableSelection; } else { if (typeof selModel === 'string') { selModel = { type: selModel }; } else { selModel.type = grid.selType || selModel.selType || selModel.type || defaultType; } if (!selModel.mode) { if (grid.simpleSelect) { selModel.mode = 'SIMPLE'; } else if (grid.multiSelect) { selModel.mode = 'MULTI'; } } selModel = Ext.Factory.selection(Ext.apply({ allowDeselect: grid.allowDeselect, locked: grid.disableSelection }, selModel)); } } return selModel; }, updateSelectionModel: function(selModel, oldSelModel) { var me = this; if (oldSelModel) { oldSelModel.un({ scope: me, lastselectedchanged: me.updateBindSelection, selectionchange: me.updateBindSelection }); Ext.destroy(me.selModelRelayer); } me.selModelRelayer = me.relayEvents(selModel, [ 'selectionchange', 'beforeselect', 'beforedeselect', 'select', 'deselect', 'focuschange' ]); selModel.on({ scope: me, lastselectedchanged: me.updateBindSelection, selectionchange: me.updateBindSelection }); me.selModel = selModel; }, getVisibleColumnManager: function() { return this.ownerCt.getVisibleColumnManager(); }, getColumnManager: function() { return this.ownerCt.getColumnManager(); }, getTopLevelVisibleColumnManager: function() { return this.ownerGrid.getVisibleColumnManager(); }, moveColumn: function(fromIdx, toIdx, colsToMove) { var me = this, multiMove = colsToMove > 1, range = multiMove && document.createRange ? document.createRange() : null, fragment = multiMove && !range ? document.createDocumentFragment() : null, destinationCellIdx = toIdx, colCount = me.getGridColumns().length, lastIndex = colCount - 1, doFirstLastClasses = (me.firstCls || me.lastCls) && (toIdx === 0 || toIdx === colCount || fromIdx === 0 || fromIdx === lastIndex), i, j, rows, len, tr, cells, colGroups; if (me.rendered && toIdx !== fromIdx) { rows = me.el.query(me.rowSelector); if (toIdx > fromIdx && fragment) { destinationCellIdx -= 1; } for (i = 0 , len = rows.length; i < len; i++) { tr = rows[i]; cells = tr.childNodes; if (doFirstLastClasses) { if (cells.length === 1) { Ext.fly(cells[0]).addCls(me.firstCls); Ext.fly(cells[0]).addCls(me.lastCls); continue; } if (fromIdx === 0) { Ext.fly(cells[0]).removeCls(me.firstCls); Ext.fly(cells[1]).addCls(me.firstCls); } else if (fromIdx === lastIndex) { Ext.fly(cells[lastIndex]).removeCls(me.lastCls); Ext.fly(cells[lastIndex - 1]).addCls(me.lastCls); } if (toIdx === 0) { Ext.fly(cells[0]).removeCls(me.firstCls); Ext.fly(cells[fromIdx]).addCls(me.firstCls); } else if (toIdx === colCount) { Ext.fly(cells[lastIndex]).removeCls(me.lastCls); Ext.fly(cells[fromIdx]).addCls(me.lastCls); } } if (multiMove) { if (range) { range.setStartBefore(cells[fromIdx]); range.setEndAfter(cells[fromIdx + colsToMove - 1]); fragment = range.extractContents(); } else { for (j = 0; j < colsToMove; j++) { fragment.appendChild(cells[fromIdx]); } } tr.insertBefore(fragment, cells[destinationCellIdx] || null); } else { tr.insertBefore(cells[fromIdx], cells[destinationCellIdx] || null); } } colGroups = me.el.query('colgroup'); for (i = 0 , len = colGroups.length; i < len; i++) { tr = colGroups[i]; if (multiMove) { if (range) { range.setStartBefore(tr.childNodes[fromIdx]); range.setEndAfter(tr.childNodes[fromIdx + colsToMove - 1]); fragment = range.extractContents(); } else { for (j = 0; j < colsToMove; j++) { fragment.appendChild(tr.childNodes[fromIdx]); } } tr.insertBefore(fragment, tr.childNodes[destinationCellIdx] || null); } else { tr.insertBefore(tr.childNodes[fromIdx], tr.childNodes[destinationCellIdx] || null); } } } }, scrollToTop: Ext.emptyFn, addElListener: function(eventName, fn, scope) { this.mon(this, eventName, fn, scope, { element: 'el' }); }, getGridColumns: function() { return this.ownerCt.getVisibleColumnManager().getColumns(); }, getHeaderAtIndex: function(index) { return this.ownerCt.getVisibleColumnManager().getHeaderAtIndex(index); }, getCell: function(record, column) { var row = this.getRow(record); return Ext.fly(row).down(column.getCellSelector()); }, getFeature: function(id) { var features = this.featuresMC; if (features) { return features.get(id); } }, findFeature: function(ftype) { if (this.features) { return Ext.Array.findBy(this.features, function(feature) { if (feature.ftype === ftype) { return true; } }); } }, initFeatures: function(grid) { var me = this, i, features, feature, len; me.tpl = Ext.XTemplate.getTpl(this, 'tpl'); me.rowTpl = Ext.XTemplate.getTpl(this, 'rowTpl'); me.addRowTpl(Ext.XTemplate.getTpl(this, 'outerRowTpl')); me.cellTpl = Ext.XTemplate.getTpl(this, 'cellTpl'); me.featuresMC = new Ext.util.MixedCollection(); features = me.features = me.constructFeatures(); len = features ? features.length : 0; for (i = 0; i < len; i++) { feature = features[i]; feature.view = me; feature.grid = grid; me.featuresMC.add(feature); feature.init(grid); } }, renderTHead: function(values, out, parent) { var headers = values.view.headerFns, len, i; if (headers) { for (i = 0 , len = headers.length; i < len; ++i) { headers[i].call(this, values, out, parent); } } }, addHeaderFn: function(fn) { var headers = this.headerFns; if (!headers) { headers = this.headerFns = []; } headers.push(fn); }, renderTFoot: function(values, out, parent) { var footers = values.view.footerFns, len, i; if (footers) { for (i = 0 , len = footers.length; i < len; ++i) { footers[i].call(this, values, out, parent); } } }, addFooterFn: function(fn) { var footers = this.footerFns; if (!footers) { footers = this.footerFns = []; } footers.push(fn); }, addTpl: function(newTpl) { return this.insertTpl('tpl', newTpl); }, addRowTpl: function(newTpl) { return this.insertTpl('rowTpl', newTpl); }, addCellTpl: function(newTpl) { return this.insertTpl('cellTpl', newTpl); }, insertTpl: function(which, newTpl) { var me = this, tpl, prevTpl; if (newTpl.isTemplate) { newTpl = Ext.Object.chain(newTpl); } else { newTpl = new Ext.XTemplate('{%this.nextTpl.applyOut(values, out, parent);%}', newTpl); } for (tpl = me[which]; newTpl.priority < tpl.priority; tpl = tpl.nextTpl) { prevTpl = tpl; } if (prevTpl) { prevTpl.nextTpl = newTpl; } else { me[which] = newTpl; } newTpl.nextTpl = tpl; return newTpl; }, tplApplyOut: function(values, out, parent) { if (this.before) { if (this.before(values, out, parent) === false) { return; } } this.nextTpl.applyOut(values, out, parent); if (this.after) { this.after(values, out, parent); } }, constructFeatures: function() { var me = this, features = me.features, feature, result, i = 0, len; if (features) { result = []; len = features.length; for (; i < len; i++) { feature = features[i]; if (!feature.isFeature) { feature = Ext.create('feature.' + feature.ftype, feature); } result[i] = feature; } } return result; }, beforeRender: function() { var me = this; me.callParent(); if (!me.enableTextSelection) { me.protoEl.unselectable(); } }, onBindStore: function(store) { var me = this, bufferedRenderer = me.bufferedRenderer; if (bufferedRenderer && bufferedRenderer.store !== store) { bufferedRenderer.bindStore(store); } if (me.all && me.all.getCount()) { if (bufferedRenderer) { bufferedRenderer.setBodyTop(0); } me.clearViewEl(); } me.callParent(arguments); }, getStoreListeners: function() { var result = this.callParent(); result.beforepageremove = this.beforePageRemove; return result; }, beforePageRemove: function(pageMap, pageNumber) { var rows = this.all, pageSize = pageMap.getPageSize(); if (rows.startIndex >= (pageNumber - 1) * pageSize && rows.endIndex <= (pageNumber * pageSize - 1)) { pageMap.get(pageNumber); return false; } }, onViewScroll: function(scroller, x, y) { if (!this.ignoreScroll) { this.callParent([ scroller, x, y ]); } }, createRowElement: function(record, index, updateColumns) { var me = this, div = me.renderBuffer, tplData = me.collectData([ record ], index); tplData.columns = updateColumns; me.tpl.overwrite(div, tplData); return Ext.fly(div).down(me.getNodeContainerSelector(), true).firstChild; }, bufferRender: function(records, index) { var me = this, div = me.renderBuffer, result, range = document.createRange ? document.createRange() : null; me.tpl.overwrite(div, me.collectData(records, index)); div = Ext.fly(div).down(me.getNodeContainerSelector(), true); if (range) { range.selectNodeContents(div); result = range.extractContents(); } else { result = document.createDocumentFragment(); while (div.firstChild) { result.appendChild(div.firstChild); } } return { fragment: result, children: Ext.Array.toArray(result.childNodes) }; }, collectData: function(records, startIndex) { var me = this; me.rowValues.view = me; me.tableValues.view = me; me.tableValues.rows = records; me.tableValues.columns = null; me.tableValues.viewStartIndex = startIndex; me.tableValues.touchScroll = me.touchScroll; me.tableValues.tableStyle = 'width:' + me.headerCt.getTableWidth() + 'px'; return me.tableValues; }, collectNodes: function(targetEl) { this.all.fill(this.getNodeContainer().childNodes, this.all.startIndex); }, refreshSize: function(forceLayout) { var me = this, bodySelector = me.getBodySelector(); if (bodySelector) { me.body.attach(me.el.down(bodySelector, true)); } if (!me.hasLoadingHeight) { Ext.suspendLayouts(); me.callParent(arguments); if (forceLayout || (me.hasVariableRowHeight() && me.dataSource.getCount())) { me.grid.updateLayout(); } Ext.resumeLayouts(true); } }, clearViewEl: function(leaveNodeContainer) { var me = this, all = me.all, store = me.getStore(), i, item, nodeContainer, targetEl; for (i = all.startIndex; i <= all.endIndex; i++) { item = all.item(i, true); me.fireEvent('itemremove', store.getByInternalId(item.getAttribute('data-recordId')), i, item, me); } me.callParent(); nodeContainer = Ext.fly(me.getNodeContainer()); if (nodeContainer && !leaveNodeContainer) { targetEl = me.getTargetEl(); if (targetEl.dom !== nodeContainer.dom) { nodeContainer.destroy(); } } }, getMaskTarget: function() { return this.ownerCt.body; }, statics: { getBoundView: function(node) { return Ext.getCmp(node.getAttribute('data-boundView')); } }, getRecord: function(node) { var me = this, recordIndex; if (me.store.isDestroyed) { return; } if (node.isModel) { return node; } node = me.getNode(node); if (node) { if (!me.hasActiveFeature()) { recordIndex = node.getAttribute('data-recordIndex'); if (recordIndex) { recordIndex = parseInt(recordIndex, 10); if (recordIndex > -1) { return me.store.data.getAt(recordIndex); } } } return me.dataSource.getByInternalId(node.getAttribute('data-recordId')); } }, indexOf: function(node) { node = this.getNode(node); if (!node && node !== 0) { return -1; } return this.all.indexOf(node); }, indexInStore: function(node) { return node ? this.dataSource.indexOf(this.getRecord(node)) : -1; }, renderRows: function(rows, columns, viewStartIndex, out) { var rowValues = this.rowValues, rowCount = rows.length, i; rowValues.view = this; rowValues.columns = columns; for (i = 0; i < rowCount; i++ , viewStartIndex++) { rowValues.itemClasses.length = rowValues.rowClasses.length = 0; this.renderRow(rows[i], viewStartIndex, out); } rowValues.view = rowValues.columns = rowValues.record = null; }, renderColumnSizer: function(values, out) { var columns = values.columns || this.getGridColumns(), len = columns.length, i, column, width; out.push(''); for (i = 0; i < len; i++) { column = columns[i]; width = column.cellWidth ? column.cellWidth : Ext.grid.header.Container.prototype.defaultWidth; out.push(''); } out.push(''); }, renderRow: function(record, rowIdx, out) { var me = this, isMetadataRecord = rowIdx === -1, selModel = me.selectionModel, rowValues = me.rowValues, itemClasses = rowValues.itemClasses, rowClasses = rowValues.rowClasses, itemCls = me.itemCls, cls, rowTpl = me.rowTpl; rowValues.rowAttr = {}; rowValues.record = record; rowValues.recordId = record.internalId; rowValues.recordIndex = me.store.indexOf(record); rowValues.rowIndex = rowIdx; rowValues.rowId = me.getRowId(record); rowValues.itemCls = rowValues.rowCls = ''; if (!rowValues.columns) { rowValues.columns = me.ownerCt.getVisibleColumnManager().getColumns(); } itemClasses.length = rowClasses.length = 0; if (!isMetadataRecord) { itemClasses[0] = itemCls; if (!me.ownerCt.disableSelection && selModel.isRowSelected) { if (selModel.isRowSelected(record)) { itemClasses.push(me.selectedItemCls); } } if (me.stripeRows && rowIdx % 2 !== 0) { itemClasses.push(me.altRowCls); } if (me.getRowClass) { cls = me.getRowClass(record, rowIdx, null, me.dataSource); if (cls) { rowClasses.push(cls); } } } if (out) { rowTpl.applyOut(rowValues, out, me.tableValues); } else { return rowTpl.apply(rowValues, me.tableValues); } }, renderCell: function(column, record, recordIndex, rowIndex, columnIndex, out) { var me = this, fullIndex, selModel = me.selectionModel, cellValues = me.cellValues, classes = cellValues.classes, fieldValue = record.data[column.dataIndex], cellTpl = me.cellTpl, value, clsInsertPoint, lastFocused = me.navigationModel.getPosition(); cellValues.record = record; cellValues.column = column; cellValues.recordIndex = recordIndex; cellValues.rowIndex = rowIndex; cellValues.columnIndex = columnIndex; cellValues.cellIndex = columnIndex; cellValues.align = column.align; cellValues.innerCls = column.innerCls; cellValues.tdCls = cellValues.tdStyle = cellValues.tdAttr = cellValues.style = ""; cellValues.unselectableAttr = me.enableTextSelection ? '' : 'unselectable="on"'; classes[1] = column.getCellId(); clsInsertPoint = 2; if (column.renderer && column.renderer.call) { fullIndex = me.ownerCt.columnManager.getHeaderIndex(column); value = column.renderer.call(column.usingDefaultRenderer ? column : column.scope || me.ownerCt, fieldValue, cellValues, record, recordIndex, fullIndex, me.dataSource, me); if (cellValues.css) { record.cssWarning = true; cellValues.tdCls += ' ' + cellValues.css; cellValues.css = null; } if (cellValues.tdCls) { classes[clsInsertPoint++] = cellValues.tdCls; } } else { value = fieldValue; } cellValues.value = (value == null || value === '') ? column.emptyCellText : value; if (column.tdCls) { classes[clsInsertPoint++] = column.tdCls; } if (me.markDirty && record.dirty && record.isModified(column.dataIndex)) { classes[clsInsertPoint++] = me.dirtyCls; } if (column.isFirstVisible) { classes[clsInsertPoint++] = me.firstCls; } if (column.isLastVisible) { classes[clsInsertPoint++] = me.lastCls; } if (!me.enableTextSelection) { classes[clsInsertPoint++] = me.unselectableCls; } if (selModel && (selModel.isCellModel || selModel.isSpreadsheetModel) && selModel.isCellSelected(me, recordIndex, column)) { classes[clsInsertPoint++] = me.selectedCellCls; } if (lastFocused && lastFocused.record.id === record.id && lastFocused.column === column) { classes[clsInsertPoint++] = me.focusedItemCls; } classes.length = clsInsertPoint; cellValues.tdCls = classes.join(' '); cellTpl.applyOut(cellValues, out); cellValues.column = null; }, getRow: function(nodeInfo) { var fly; if ((!nodeInfo && nodeInfo !== 0) || !this.rendered) { return null; } if (nodeInfo.target) { nodeInfo = nodeInfo.target; } if (Ext.isString(nodeInfo)) { return Ext.fly(nodeInfo).down(this.rowSelector, true); } if (Ext.isNumber(nodeInfo)) { fly = this.all.item(nodeInfo); return fly && fly.down(this.rowSelector, true); } if (nodeInfo.isModel) { return this.getRowByRecord(nodeInfo); } fly = Ext.fly(nodeInfo); if (fly.is(this.itemSelector)) { return this.getRowFromItem(fly); } return fly.findParent(this.rowSelector, this.getTargetEl()); }, getRowId: function(record) { return this.id + '-record-' + record.internalId; }, constructRowId: function(internalId) { return this.id + '-record-' + internalId; }, getNodeById: function(id) { id = this.constructRowId(id); return this.retrieveNode(id, false); }, getRowById: function(id) { id = this.constructRowId(id); return this.retrieveNode(id, true); }, getNodeByRecord: function(record) { return this.retrieveNode(this.getRowId(record), false); }, getRowByRecord: function(record) { return this.retrieveNode(this.getRowId(record), true); }, getRowFromItem: function(item) { var rows = Ext.getDom(item).tBodies[0].childNodes, len = rows.length, i; for (i = 0; i < len; i++) { if (Ext.fly(rows[i]).is(this.rowSelector)) { return rows[i]; } } }, retrieveNode: function(id, dataRow) { var result = this.el.getById(id, true); if (dataRow && result) { return Ext.fly(result).down(this.rowSelector, true); } return result; }, updateIndexes: Ext.emptyFn, bodySelector: 'div.' + Ext.baseCSSPrefix + 'grid-item-container', nodeContainerSelector: 'div.' + Ext.baseCSSPrefix + 'grid-item-container', itemSelector: 'table.' + Ext.baseCSSPrefix + 'grid-item', rowSelector: 'tr.' + Ext.baseCSSPrefix + 'grid-row', cellSelector: 'td.' + Ext.baseCSSPrefix + 'grid-cell', sizerSelector: '.' + Ext.baseCSSPrefix + 'grid-cell', innerSelector: 'div.' + Ext.baseCSSPrefix + 'grid-cell-inner', getBodySelector: function() { return this.bodySelector; }, getColumnSizerSelector: function(header) { var selector = this.sizerSelector + '-' + header.getItemId(); return 'td' + selector + ',col' + selector; }, getItemSelector: function() { return this.itemSelector; }, getCellSelector: function(header) { return header ? header.getCellSelector() : this.cellSelector; }, getCellInnerSelector: function(header) { return this.getCellSelector(header) + ' ' + this.innerSelector; }, addRowCls: function(rowInfo, cls) { var row = this.getRow(rowInfo); if (row) { Ext.fly(row).addCls(cls); } }, removeRowCls: function(rowInfo, cls) { var row = this.getRow(rowInfo); if (row) { Ext.fly(row).removeCls(cls); } }, onRowSelect: function(rowIdx) { var me = this; me.addItemCls(rowIdx, me.selectedItemCls); if (Ext.isIE8) { me.repaintBorder(rowIdx + 1); } }, onRowDeselect: function(rowIdx) { var me = this; me.removeItemCls(rowIdx, me.selectedItemCls); if (Ext.isIE8) { me.repaintBorder(rowIdx + 1); } }, onCellSelect: function(position) { var cell = this.getCellByPosition(position); if (cell) { cell.addCls(this.selectedCellCls); } }, onCellDeselect: function(position) { var cell = this.getCellByPosition(position, true); if (cell) { Ext.fly(cell).removeCls(this.selectedCellCls); } }, getCellInclusive: function(position, returnDom) { if (position) { var row = this.getRow(position.row), header = this.ownerCt.getColumnManager().getHeaderAtIndex(position.column); if (header && row) { return Ext.fly(row).down(this.getCellSelector(header), returnDom); } } return false; }, getCellByPosition: function(position, returnDom) { if (position) { var view = position.view || this, row = view.getRow(position.record || position.row), header = position.column.isColumn ? position.column : view.getVisibleColumnManager().getHeaderAtIndex(position.column); if (header && row) { return Ext.fly(row).down(view.getCellSelector(header), returnDom); } } return false; }, onFocusEnter: function(e) { var me = this, targetView, navigationModel = me.getNavigationModel(), lastFocused, focusPosition, br = me.bufferedRenderer, firstRecord, focusTarget; e = e.event; if (!me.cellFocused && me.all.getCount() && me.dataSource.getCount()) { focusTarget = e.getTarget(); if (focusTarget && me.el.contains(focusTarget) && focusTarget !== me.el.dom && !Ext.fly(focusTarget).is(me.getCellSelector())) { if (navigationModel.lastFocused) { navigationModel.position = navigationModel.lastFocused; } me.cellFocused = true; } else { lastFocused = focusPosition = me.getLastFocused(); if (!focusPosition) { targetView = me.isNormalView ? (me.lockingPartner.isVisible() ? me.lockingPartner : me.normalView) : me; firstRecord = me.dataSource.getAt(br ? br.getFirstVisibleRowIndex() : 0); if (firstRecord && !firstRecord.isNonData) { focusPosition = new Ext.grid.CellContext(targetView).setPosition({ row: firstRecord, column: 0 }); } } if (!focusPosition) { e.stopEvent(); e.getTarget().blur(); return; } navigationModel.setPosition(focusPosition, null, e, null, true); me.cellFocused = !!navigationModel.getPosition(); } } if (me.cellFocused) { me.el.dom.setAttribute('tabindex', '-1'); } }, onFocusLeave: function(e) { var me = this; if (me.cellFocused) { if (e.toComponent !== me.lockingPartner) { me.getNavigationModel().setPosition(null, null, e.event, null, true); } me.cellFocused = false; me.focusEl = me.el; me.focusEl.dom.setAttribute('tabindex', 0); } }, onRowFocus: function(rowIdx, highlight, supressFocus) { var me = this; if (highlight) { me.addItemCls(rowIdx, me.focusedItemCls); if (!supressFocus) { me.focusRow(rowIdx); } } else { me.removeItemCls(rowIdx, me.focusedItemCls); } if (Ext.isIE8) { me.repaintBorder(rowIdx + 1); } }, focusRow: function(row, delay) { var me = this, focusTask = me.getFocusTask(); if (delay) { focusTask.delay(Ext.isNumber(delay) ? delay : 10, me.focusRow, me, [ row, false ]); return; } focusTask.cancel(); if (me.isVisible(true)) { me.getNavigationModel().setPosition(me.getRecord(row)); } }, focusNode: function(row, delay) { this.focusRow(row, delay); }, scrollRowIntoView: function(row, animate) { row = this.getRow(row); if (row) { this.scrollElIntoView(row, false, animate); } }, focusCell: function(position, delay) { var me = this, cell, focusTask = me.getFocusTask(); if (delay) { focusTask.delay(Ext.isNumber(delay) ? delay : 10, me.focusCell, me, [ position, false ]); return; } focusTask.cancel(); if (me.isVisible(true) && (cell = me.getCellByPosition(position))) { me.getNavigationModel().setPosition(position); } }, getLastFocused: function() { var me = this, lastFocused = me.lastFocused; if (lastFocused && lastFocused.record && lastFocused.column) { if (me.dataSource.indexOf(lastFocused.record) !== -1 && me.getVisibleColumnManager().indexOf(lastFocused.column) !== -1 && me.getNode(lastFocused.record)) { return lastFocused; } } }, scrollCellIntoView: function(cell, animate) { if (cell.isCellContext) { cell = this.getCellByPosition(cell); } if (cell) { this.scrollElIntoView(cell, null, animate); } }, scrollElIntoView: function(el, hscroll, animate) { var scroller = this.getScrollable(); if (scroller) { scroller.scrollIntoView(el, hscroll, animate); } }, syncRowHeightBegin: function() { var me = this, itemEls = me.all, ln = itemEls.count, synchronizer = [], RowSynchronizer = Ext.grid.locking.RowSynchronizer, i, j, rowSync; for (i = 0 , j = itemEls.startIndex; i < ln; i++ , j++) { synchronizer[i] = rowSync = new RowSynchronizer(me, itemEls.elements[j]); rowSync.reset(); } return synchronizer; }, syncRowHeightClear: function(synchronizer) { var me = this, itemEls = me.all, ln = itemEls.count, i; for (i = 0; i < ln; i++) { synchronizer[i].reset(); } }, syncRowHeightMeasure: function(synchronizer) { var ln = synchronizer.length, i; for (i = 0; i < ln; i++) { synchronizer[i].measure(); } }, syncRowHeightFinish: function(synchronizer, otherSynchronizer) { var ln = synchronizer.length, bufferedRenderer = this.bufferedRenderer, i; for (i = 0; i < ln; i++) { synchronizer[i].finish(otherSynchronizer[i]); } if (bufferedRenderer) { bufferedRenderer.syncRowHeightsFinish(); } }, handleUpdate: function(store, record, operation, changedFieldNames) { operation = operation || Ext.data.Model.EDIT; var me = this, rowTpl = me.rowTpl, markDirty = me.markDirty, dirtyCls = me.dirtyCls, clearDirty = operation !== Ext.data.Model.EDIT, columnsToUpdate = [], hasVariableRowHeight = me.variableRowHeight, updateTypeFlags = 0, ownerCt = me.ownerCt, cellFly = me.cellFly || (me.self.prototype.cellFly = new Ext.dom.Fly()), oldItem, oldItemDom, oldDataRow, newItemDom, newAttrs, attLen, attName, attrIndex, overItemCls, columns, column, len, i, cellUpdateFlag, cell, fieldName, value, defaultRenderer, scope, elData, emptyValue; if (me.viewReady) { oldItemDom = me.getNodeByRecord(record); if (oldItemDom) { overItemCls = me.overItemCls; columns = me.ownerCt.getVisibleColumnManager().getColumns(); for (i = 0 , len = columns.length; i < len; i++) { column = columns[i]; if (column.preventUpdate) { cell = Ext.fly(oldItemDom).down(column.getCellSelector(), true); if (!clearDirty && markDirty) { cellFly.attach(cell); if (record.isModified(column.dataIndex)) { cellFly.addCls(dirtyCls); } else { cellFly.removeCls(dirtyCls); } } } else { cellUpdateFlag = me.shouldUpdateCell(record, column, changedFieldNames); if (cellUpdateFlag) { updateTypeFlags = updateTypeFlags | cellUpdateFlag; columnsToUpdate[columnsToUpdate.length] = column; hasVariableRowHeight = hasVariableRowHeight || column.variableRowHeight; } } } if (me.getRowClass || !me.getRowFromItem(oldItemDom) || (updateTypeFlags & 1) || (oldItemDom.tBodies[0].childNodes.length > 1)) { oldItem = Ext.fly(oldItemDom, '_internal'); elData = oldItemDom._extData; newItemDom = me.createRowElement(record, me.dataSource.indexOf(record), columnsToUpdate); if (oldItem.hasCls(overItemCls)) { Ext.fly(newItemDom).addCls(overItemCls); } if (Ext.isIE9m && oldItemDom.mergeAttributes) { oldItemDom.mergeAttributes(newItemDom, true); } else { newAttrs = newItemDom.attributes; attLen = newAttrs.length; for (attrIndex = 0; attrIndex < attLen; attrIndex++) { attName = newAttrs[attrIndex].name; if (attName !== 'id') { oldItemDom.setAttribute(attName, newAttrs[attrIndex].value); } } } if (elData) { elData.isSynchronized = false; } if (columns.length && (oldDataRow = me.getRow(oldItemDom))) { me.updateColumns(oldDataRow, Ext.fly(newItemDom).down(me.rowSelector, true), columnsToUpdate); } while (rowTpl) { if (rowTpl.syncContent) { if (rowTpl.syncContent(oldItemDom, newItemDom, changedFieldNames ? columnsToUpdate : null) === false) { break; } } rowTpl = rowTpl.nextTpl; } } else { for (i = 0 , len = columnsToUpdate.length; i < len; i++) { column = columnsToUpdate[i]; fieldName = column.dataIndex; value = record.get(fieldName); cell = Ext.fly(oldItemDom).down(column.getCellSelector(), true); if (!clearDirty && markDirty) { cellFly.attach(cell); if (record.isModified(column.dataIndex)) { cellFly.addCls(dirtyCls); } else { cellFly.removeCls(dirtyCls); } } defaultRenderer = column.usingDefaultRenderer; scope = defaultRenderer ? column : column.scope; if (column.updater) { Ext.callback(column.updater, scope, [ cell, value, record, me, me.dataSource ], 0, column, ownerCt); } else { if (column.renderer) { value = Ext.callback(column.renderer, scope, [ value, null, record, 0, 0, me.dataSource, me ], 0, column, ownerCt); } emptyValue = value == null || value === ''; value = emptyValue ? column.emptyCellText : value; if (column.producesHTML || emptyValue) { cell.childNodes[0].innerHTML = value; } else { cell.childNodes[0].childNodes[0].data = value; } } if (me.highlightClass) { Ext.fly(cell).addCls(me.highlightClass); if (!me.changedCells) { me.self.prototype.changedCells = []; me.prototype.clearChangedTask = new Ext.util.DelayedTask(me.clearChangedCells, me.prototype); me.clearChangedTask.delay(me.unhighlightDelay); } me.changedCells.push({ cell: cell, cls: me.highlightClass, expires: Ext.Date.now() + 1000 }); } } } if (clearDirty && markDirty && !record.dirty) { Ext.fly(oldItemDom, '_internal').select('.' + dirtyCls).removeCls(dirtyCls); } if (hasVariableRowHeight) { Ext.suspendLayouts(); } me.fireEvent('itemupdate', record, me.store.indexOf(record), oldItemDom); if (hasVariableRowHeight) { if (me.bufferedRenderer) { me.bufferedRenderer.refreshSize(); me.ownerGrid.updateLayout(); } else { me.refreshSize(); } Ext.resumeLayouts(true); } } } }, clearChangedCells: function() { var me = this, now = Ext.Date.now(), changedCell; for (var i = 0, len = me.changedCells.length; i < len; ) { changedCell = me.changedCells[i]; if (changedCell.expires <= now) { Ext.fly(changedCell.cell).removeCls(changedCell.highlightClass); Ext.Array.erase(me.changedCells, i, 1); len--; } else { break; } } if (len) { me.clearChangedTask.delay(me.unhighlightDelay); } }, updateColumns: function(oldRowDom, newRowDom, columnsToUpdate) { var me = this, newAttrs, attLen, attName, attrIndex, colCount = columnsToUpdate.length, colIndex, column, oldCell, newCell, cellSelector = me.getCellSelector(); if (oldRowDom.mergeAttributes) { oldRowDom.mergeAttributes(newRowDom, true); } else { newAttrs = newRowDom.attributes; attLen = newAttrs.length; for (attrIndex = 0; attrIndex < attLen; attrIndex++) { attName = newAttrs[attrIndex].name; if (attName !== 'id') { oldRowDom.setAttribute(attName, newAttrs[attrIndex].value); } } } for (colIndex = 0; colIndex < colCount; colIndex++) { column = columnsToUpdate[colIndex]; cellSelector = me.getCellSelector(column); oldCell = Ext.fly(oldRowDom).selectNode(cellSelector); newCell = Ext.fly(newRowDom).selectNode(cellSelector); Ext.fly(oldCell).syncContent(newCell); } }, shouldUpdateCell: function(record, column, changedFieldNames) { if (!column.preventUpdate) { if (column.hasCustomRenderer) { return 1; } if (changedFieldNames) { var len = changedFieldNames.length, i, field; for (i = 0; i < len; ++i) { field = changedFieldNames[i]; if (field === column.dataIndex || field === record.idProperty) { return 2; } } } else { return 2; } } return 0; }, refresh: function() { var me = this, scroller; me.callParent(arguments); me.headerCt.setSortState(); if (me.touchScroll && me.el && !me.all.getCount() && me.headerCt && me.headerCt.tooNarrow) { scroller = me.getScrollable(); if (scroller) { scroller.setSize({ x: me.headerCt.getTableWidth(), y: scroller.getSize().y }); } } }, processContainerEvent: function(e) { var cmp = Ext.Component.fromElement(e.target.parentNode); if (cmp && cmp.up(this.ownerCt)) { return false; } }, processItemEvent: function(record, item, rowIndex, e) { var me = this, self = me.self, map = self.EventMap, type = e.type, features = me.features, len = features.length, i, cellIndex, result, feature, column, navModel = me.getNavigationModel(), eventPosition = e.position = me.eventPosition || (me.eventPosition = new Ext.grid.CellContext()), focusPosition, row, cell; if (Ext.isIE && type === 'mouseup' && !e.within(me.el)) { return false; } if (me.indexInStore(item) !== -1) { row = eventPosition.rowElement = Ext.fly(item).down(me.rowSelector, true); if (Ext.String.startsWith(e.type, 'key') && (focusPosition = navModel.getPosition())) { cell = (cell = navModel.getCell()) && cell.dom; column = focusPosition.column; } if (!cell) { cell = e.getTarget(me.getCellSelector(), row); } type = self.TouchEventMap[type] || type; if (cell) { if (!cell.parentNode) { return false; } if (!column) { column = me.getHeaderByCell(cell); } cellIndex = me.ownerCt.getColumnManager().getHeaderIndex(column); } else { cellIndex = -1; } eventPosition.setAll(me, rowIndex, column ? me.getVisibleColumnManager().getHeaderIndex(column) : -1, record, column); eventPosition.cellElement = cell; result = me.fireEvent('uievent', type, me, cell, rowIndex, cellIndex, e, record, row); if ((result === false || me.callParent(arguments) === false)) { return false; } for (i = 0; i < len; ++i) { feature = features[i]; if (feature.wrapsItem) { if (feature.vetoEvent(record, row, rowIndex, e) === false) { me.processSpecialEvent(e); e.preventDefault(); return false; } } } if (cell && type !== 'mouseover' && type !== 'mouseout') { result = ! ((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)); } if (result !== false) { result = me.fireEvent('row' + type, me, record, row, rowIndex, e); } return result; } else { this.processSpecialEvent(e); e.preventDefault(); return false; } }, processSpecialEvent: function(e) { var me = this, features = me.features, ln = features.length, type = e.type, i, feature, prefix, featureTarget, beforeArgs, args, panel = me.ownerCt; me.callParent(arguments); if (type === 'mouseover' || type === 'mouseout') { return; } type = me.self.TouchEventMap[type] || type; 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, e); args = feature.getFireEventArgs(prefix + type, me, featureTarget, e); 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; } } } } return true; }, onCellMouseDown: Ext.emptyFn, onCellLongPress: Ext.emptyFn, onCellMouseUp: Ext.emptyFn, onCellClick: Ext.emptyFn, onCellDblClick: Ext.emptyFn, onCellContextMenu: Ext.emptyFn, onCellKeyDown: Ext.emptyFn, onCellKeyUp: Ext.emptyFn, onCellKeyPress: Ext.emptyFn, onBeforeCellMouseDown: Ext.emptyFn, onBeforeCellLongPress: Ext.emptyFn, onBeforeCellMouseUp: Ext.emptyFn, onBeforeCellClick: Ext.emptyFn, onBeforeCellDblClick: Ext.emptyFn, onBeforeCellContextMenu: Ext.emptyFn, onBeforeCellKeyDown: Ext.emptyFn, onBeforeCellKeyUp: Ext.emptyFn, onBeforeCellKeyPress: Ext.emptyFn, expandToFit: function(header) { this.autoSizeColumn(header); }, autoSizeColumn: function(header) { if (Ext.isNumber(header)) { header = this.getGridColumns()[header]; } if (header) { if (header.isGroupHeader) { header.autoSize(); return; } delete header.flex; header.setWidth(this.getMaxContentWidth(header)); } }, getMaxContentWidth: function(header) { var me = this, cells = me.el.query(header.getCellInnerSelector()), originalWidth = header.getWidth(), i = 0, ln = cells.length, columnSizer = me.body.select(me.getColumnSizerSelector(header)), max = Math.max, widthAdjust = 0, maxWidth; if (ln > 0) { if (Ext.supports.ScrollWidthInlinePaddingBug) { widthAdjust += me.getCellPaddingAfter(cells[0]); } if (me.columnLines) { widthAdjust += Ext.fly(cells[0].parentNode).getBorderWidth('lr'); } } columnSizer.setWidth(1); header.textEl.setStyle({ "text-overflow": 'clip', display: 'table-cell' }); maxWidth = header.textEl.dom.offsetWidth + header.titleEl.getPadding('lr'); header.textEl.setStyle({ "text-overflow": '', display: '' }); for (; i < ln; i++) { maxWidth = max(maxWidth, cells[i].scrollWidth); } maxWidth += widthAdjust; maxWidth = max(maxWidth + 1, 40); columnSizer.setWidth(originalWidth); return maxWidth; }, getPositionByEvent: function(e) { var me = this, cellNode = e.getTarget(me.cellSelector), rowNode = e.getTarget(me.itemSelector), record = me.getRecord(rowNode), header = me.getHeaderByCell(cellNode); return me.getPosition(record, header); }, getHeaderByCell: function(cell) { if (cell) { return this.ownerCt.getVisibleColumnManager().getHeaderById(cell.getAttribute('data-columnId')); } return false; }, walkCells: function(pos, direction, e, preventWrap, verifierFn, scope) { if (!pos) { return false; } var me = this, row = typeof pos.row === 'number' ? pos.row : pos.rowIdx, column = typeof pos.column === 'number' ? pos.column : pos.colIdx, rowCount = me.dataSource.getCount(), columns = me.ownerCt.getVisibleColumnManager(), firstIndex = columns.getHeaderIndex(columns.getFirst()), lastIndex = columns.getHeaderIndex(columns.getLast()), newRow = row, newColumn = column, activeHeader = columns.getHeaderAtIndex(column); if (!activeHeader || activeHeader.hidden || !rowCount) { return false; } e = e || {}; direction = direction.toLowerCase(); switch (direction) { case 'right': if (column === lastIndex) { if (preventWrap || row === rowCount - 1) { return false; } if (!e.ctrlKey) { newRow = me.walkRows(row, 1); if (newRow !== row) { newColumn = firstIndex; } } } else { if (!e.ctrlKey) { newColumn = columns.getHeaderIndex(columns.getNextSibling(activeHeader)); } else { newColumn = lastIndex; } }; break; case 'left': if (column === firstIndex) { if (preventWrap || row === 0) { return false; } if (!e.ctrlKey) { newRow = me.walkRows(row, -1); if (newRow !== row) { newColumn = lastIndex; } } } else { if (!e.ctrlKey) { newColumn = columns.getHeaderIndex(columns.getPreviousSibling(activeHeader)); } else { newColumn = firstIndex; } }; break; case 'up': if (row === 0) { return false; } else { if (!e.ctrlKey) { newRow = me.walkRows(row, -1); } else { newRow = me.walkRows(-1, 1); } }; break; case 'down': if (row === rowCount - 1) { return false; } else { if (!e.ctrlKey) { newRow = me.walkRows(row, 1); } else { newRow = me.walkRows(rowCount, -1); } }; break; } if (verifierFn && verifierFn.call(scope || me, { row: newRow, column: newColumn }) !== true) { return false; } newColumn = columns.getHeaderAtIndex(newColumn); return new Ext.grid.CellContext(me).setPosition(newRow, newColumn); }, walkRows: function(startRow, distance) { var me = this, store = me.dataSource, moved = 0, lastValid = startRow, node, limit = (distance < 0) ? 0 : (store.isBufferedStore ? store.getTotalCount() : store.getCount()) - 1, increment = limit ? 1 : -1, result = startRow; do { if (limit ? result >= limit : result <= limit) { return lastValid || limit; } result += increment; if ((node = Ext.fly(me.getRow(result))) && node.isVisible(true)) { moved += increment; lastValid = result; } } while ( moved !== distance); return result; }, walkRecs: function(startRec, distance) { var me = this, store = me.dataSource, moved = 0, lastValid = startRec, node, limit = (distance < 0) ? 0 : (store.isBufferedStore ? store.getTotalCount() : store.getCount()) - 1, increment = limit ? 1 : -1, testIndex = store.indexOf(startRec), rec; do { if (limit ? testIndex >= limit : testIndex <= limit) { return lastValid; } testIndex += increment; rec = store.getAt(testIndex); if (!rec.isCollapsedPlaceholder && (node = Ext.fly(me.getNodeByRecord(rec))) && node.isVisible(true)) { moved += increment; lastValid = rec; } } while ( moved !== distance); return lastValid; }, getFirstVisibleRowIndex: function() { var me = this, count = (me.dataSource.isBufferedStore ? me.dataSource.getTotalCount() : me.dataSource.getCount()), result = me.indexOf(me.all.first()) - 1; do { result += 1; if (result === count) { return; } } while (!Ext.fly(me.getRow(result)).isVisible(true)); return result; }, getLastVisibleRowIndex: function() { var me = this, result = me.indexOf(me.all.last()); do { result -= 1; if (result === -1) { return; } } while (!Ext.fly(me.getRow(result)).isVisible(true)); return result; }, getHeaderCt: function() { return this.headerCt; }, getPosition: function(record, header) { return new Ext.grid.CellContext(this).setPosition(record, header); }, onDestroy: function() { var me = this, features = me.featuresMC, len, i; if (features) { for (i = 0 , len = features.getCount(); i < len; ++i) { features.getAt(i).destroy(); } } me.cellFly = me.featuresMC = null; me.callParent(arguments); }, onReplace: function(store, startIndex, oldRecords, newRecords) { var me = this, bufferedRenderer = me.bufferedRenderer; if (me.rendered && bufferedRenderer) { bufferedRenderer.onReplace(store, startIndex, oldRecords, newRecords); } else { me.callParent(arguments); } me.setPendingStripe(startIndex); }, onAdd: function(store, records, index) { var me = this, bufferedRenderer = me.bufferedRenderer; if (me.rendered && bufferedRenderer) { bufferedRenderer.onReplace(store, index, [], records); } else { me.callParent(arguments); } me.setPendingStripe(index); }, onRemove: function(store, records, index) { var me = this, bufferedRenderer = me.bufferedRenderer; if (me.rendered && bufferedRenderer) { bufferedRenderer.onReplace(store, index, records, []); } else { me.callParent(arguments); } me.setPendingStripe(index); }, onDataRefresh: function() { var me = this, owner = me.ownerCt; if (owner && owner.isCollapsingOrExpanding === 2) { owner.on('expand', me.onDataRefresh, me, { single: true }); return; } me.callParent(); }, getViewRange: function() { var me = this; if (me.bufferedRenderer) { return me.bufferedRenderer.getViewRange(); } return me.callParent(); }, setPendingStripe: function(index) { var current = this.stripeOnUpdate; if (current === null) { current = index; } else { current = Math.min(current, index); } this.stripeOnUpdate = current; }, onEndUpdate: function() { var me = this, stripeOnUpdate = me.stripeOnUpdate, startIndex = me.all.startIndex; if (me.rendered && (stripeOnUpdate || stripeOnUpdate === 0)) { if (stripeOnUpdate < startIndex) { stripeOnUpdate = startIndex; } me.doStripeRows(stripeOnUpdate); me.stripeOnUpdate = null; } me.callParent(arguments); }, doStripeRows: function(startRow, endRow) { var me = this, rows, rowsLn, i, row; if (me.rendered && me.stripeRows) { rows = me.getNodes(startRow, endRow); for (i = 0 , rowsLn = rows.length; i < rowsLn; i++) { row = rows[i]; row.className = row.className.replace(me.rowClsRe, ' '); startRow++; if (startRow % 2 === 0) { row.className += (' ' + me.altRowCls); } } } }, hasActiveFeature: function() { return (this.isGrouping && this.store.isGrouped()) || this.isRowWrapped; }, getCellPaddingAfter: function(cell) { return Ext.fly(cell).getPadding('r'); }, privates: { refreshScroll: function() { var me = this, bufferedRenderer = me.bufferedRenderer; if (bufferedRenderer) { bufferedRenderer.refreshSize(); } else { me.callParent(); } } } }); Ext.define('Ext.grid.Panel', { extend: 'Ext.panel.Table', requires: [ 'Ext.view.Table' ], alias: [ 'widget.gridpanel', 'widget.grid' ], alternateClassName: [ 'Ext.list.ListView', 'Ext.ListView', 'Ext.grid.GridPanel' ], viewType: 'tableview', lockable: false, rowLines: true }); Ext.define('Ext.form.CheckboxManager', { extend: 'Ext.util.MixedCollection', singleton: true, getByName: function(name, formId) { return this.filterBy(function(item) { return item.name === name && item.getFormId() === formId; }); } }); 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' ], stretchInputElFixed: false, childEls: [ 'boxLabelEl', 'innerWrapEl' ], fieldSubTpl: [ '', { disableFormats: true, compiled: true } ], publishes: { checked: 1 }, subTplInsertions: [ 'beforeBoxLabelTpl', 'afterBoxLabelTpl', 'beforeBoxLabelTextTpl', 'afterBoxLabelTextTpl', 'boxLabelAttrTpl', 'inputAttrTpl' ], isCheckbox: true, focusCls: 'form-checkbox-focus', fieldBodyCls: Ext.baseCSSPrefix + 'form-cb-wrap', checked: false, checkedCls: Ext.baseCSSPrefix + 'form-cb-checked', boxLabelCls: Ext.baseCSSPrefix + 'form-cb-label', boxLabelAlign: 'after', afterLabelCls: Ext.baseCSSPrefix + 'form-cb-after', wrapInnerCls: Ext.baseCSSPrefix + 'form-cb-wrap-inner', noBoxLabelCls: Ext.baseCSSPrefix + 'form-cb-wrap-inner-no-box-label', inputValue: 'on', checkChangeEvents: [], inputType: 'checkbox', isTextInput: false, ariaRole: 'checkbox', onRe: /^on$/i, inputCls: Ext.baseCSSPrefix + 'form-cb', initComponent: function() { var me = this, value = me.value; if (value !== undefined) { me.checked = me.isChecked(value, me.inputValue); } me.callParent(arguments); me.getManager().add(me); }, initValue: function() { var me = this, checked = !!me.checked; me.originalValue = me.lastValue = checked; me.setValue(checked); }, getElConfig: function() { var me = this; if (me.isChecked(me.rawValue, me.inputValue)) { me.addCls(me.checkedCls); } return me.callParent(); }, getSubTplData: function(fieldData) { var me = this, boxLabel = me.boxLabel, boxLabelAlign = me.boxLabelAlign, labelAlignedBefore = boxLabelAlign === 'before'; return Ext.apply(me.callParent(arguments), { disabled: me.readOnly || me.disabled, wrapInnerCls: me.wrapInnerCls, boxLabel: boxLabel, boxLabelCls: me.boxLabelCls, boxLabelAlign: boxLabelAlign, labelAlignedBefore: labelAlignedBefore, afterLabelCls: labelAlignedBefore ? me.afterLabelCls : '', noBoxLabelCls: !boxLabel ? me.noBoxLabelCls : '', role: me.ariaRole }); }, initEvents: function() { var me = this; me.callParent(); me.mon(me.inputEl, 'click', me.onBoxClick, me, { translate: false }); }, setBoxLabel: function(boxLabel) { var me = this; me.boxLabel = boxLabel; if (me.rendered) { me.boxLabelEl.setHtml(boxLabel); me.innerWrapEl[boxLabel ? 'removeCls' : 'addCls'](me.noBoxLabelCls); me.updateLayout(); } }, onBoxClick: function() { var me = this; if (!me.disabled && !me.readOnly) { me.setValue(!me.checked); } }, getRawValue: function() { return this.checked; }, getValue: function() { return this.checked; }, getSubmitValue: function() { var unchecked = this.uncheckedValue, uncheckedVal = Ext.isDefined(unchecked) ? unchecked : null; return this.checked ? this.inputValue : uncheckedVal; }, isChecked: function(rawValue, inputValue) { return (rawValue === true || rawValue === 'true' || rawValue === '1' || rawValue === 1 || (((Ext.isString(rawValue) || Ext.isNumber(rawValue)) && inputValue) ? rawValue == inputValue : this.onRe.test(rawValue))); }, setRawValue: function(value) { var me = this, inputEl = me.inputEl, checked = me.isChecked(value, me.inputValue); if (inputEl) { me[checked ? 'addCls' : 'removeCls'](me.checkedCls); } me.checked = me.rawValue = checked; if (!me.duringSetValue) { me.lastValue = checked; } return checked; }, setValue: function(checked) { var me = this, boxes, i, len, box; if (Ext.isArray(checked)) { boxes = me.getManager().getByName(me.name, me.getFormId()).items; len = boxes.length; for (i = 0; i < len; ++i) { box = boxes[i]; box.setValue(Ext.Array.contains(checked, box.inputValue)); } } else { me.duringSetValue = true; me.callParent(arguments); delete me.duringSetValue; } return me; }, valueToRaw: Ext.identityFn, onChange: function(newVal, oldVal) { var me = this, handler = me.handler; if (handler) { Ext.callback(handler, me.scope, [ me, newVal ], 0, me); } me.callParent(arguments); if (me.reference && me.publishState) { me.publishState('checked', newVal); } }, resetOriginalValue: function( fromBoxInGroup) { var me = this, boxes, box, len, i; if (!fromBoxInGroup) { boxes = me.getManager().getByName(me.name, me.getFormId()).items; len = boxes.length; for (i = 0; i < len; ++i) { box = boxes[i]; if (box !== me) { boxes[i].resetOriginalValue(true); } } } me.callParent(); }, beforeDestroy: function() { this.callParent(); this.getManager().removeAtKey(this.id); }, getManager: function() { return Ext.form.CheckboxManager; }, onEnable: function() { var me = this, inputEl = me.inputEl; me.callParent(); if (inputEl) { inputEl.dom.disabled = me.readOnly; } }, setReadOnly: function(readOnly) { var me = this, inputEl = me.inputEl; if (inputEl) { inputEl.dom.disabled = !!readOnly || me.disabled; } me.callParent(arguments); }, getFormId: function() { var me = this, form; if (!me.formId) { form = me.up('form'); if (form) { me.formId = form.id; } } return me.formId; } }); Ext.define('Ext.app.bindinspector.Util', { singleton: true, getChildStub: function(name, parent) { var val, children; if (parent) { children = parent.children; if (children) { val = children[name]; } } return val || null; }, valueRenderer: function(v) { var s; if (v === undefined) { return 'undefined'; } else if (v === null) { return 'null'; } else if (Ext.isString(v)) { return v; } else if (Ext.isDate(v)) { return Ext.Date.format(v, 'c'); } else if (v && v.isModel) { s = v.entityName; return Ext.String.format('Model({0}, {1})', s.replace('noconflict.', ''), v.getId()); } else if (v && v.isStore) { s = v.entityName || 'Anonymous'; return 'Store{' + s.replace('noconflict.', '') + '}'; } return v; }, buildBindData: function(bind) { var out = [], key, o; for (key in bind) { o = bind[key]; out.push({ key: key, descriptor: o.descriptor, tokens: o.tokens, value: o.value, binding: o }); } return out; } }); Ext.define('Ext.app.bindinspector.ComponentDetail', { extend: 'Ext.panel.Panel', alias: 'widget.bindinspector-componentdetail', requires: [ 'Ext.form.field.Display', 'Ext.grid.Panel', 'Ext.layout.container.VBox', 'Ext.form.field.Checkbox', 'Ext.app.bindinspector.Util' ], layout: 'border', activeCls: Ext.baseCSSPrefix + 'bindinspector-stub-active', descriptorCls: Ext.baseCSSPrefix + 'bindinspector-descriptor', multipleCls: Ext.baseCSSPrefix + 'bindinspector-mult-val', directCls: Ext.baseCSSPrefix + 'bindinspector-direct-val', inheritedCls: Ext.baseCSSPrefix + 'bindinspector-inherited-val', componentKeyCls: Ext.baseCSSPrefix + 'bindinspector-comp-key', componentDescCls: Ext.baseCSSPrefix + 'bindinspector-comp-desc', componentValCls: Ext.baseCSSPrefix + 'bindinspector-comp-val', lastItemCls: Ext.baseCSSPrefix + 'bindinspector-last-item', vmPreviewDefault: { xtype: 'container', region: 'east', split: true, width: '50%', cls: Ext.baseCSSPrefix + 'bindinspector-prev-default', padding: 20, layout: { type: 'hbox', align: 'middle', pack: 'center' }, items: [ { xtype: 'component', flex: 1, html: 'Select a component with a ViewModel (or inherited ViewModel) from the ComponentList to view the ViewModel details' } ] }, initComponent: function() { var me = this, comp = me.component || {}, env = me.env, publishes = comp.publishes, bindings = comp.bindings, title = 'Bindings    ⇒    ', vm = env.getInheritedVM(comp), bindData, publishesTbar; me.bindingsPreviewDefault = { xtype: 'panel', border: false, region: 'center', cls: Ext.baseCSSPrefix + 'bindinspector-prev-default', bodyPadding: 20, layout: { type: 'hbox', align: 'middle', pack: 'center' }, items: [ { xtype: 'component', flex: 1, html: 'Select a component with bindings from the ComponentList to view the bindings details along with the component\'s inherited ViewModel' } ], dockedItems: [ { xtype: 'toolbar', dock: 'top', defaultButtonUI: 'default', items: [ '->', { text: 'Open in dedicated tab', handler: function(btn) { btn.up('bindinspector-container').onComponentDblclick(null, comp); } } ] } ] }; if (comp.reference) { title += '[' + comp.reference + '] • '; } bindData = comp.bindData || Ext.app.bindinspector.Util.buildBindData(bindings); if (publishes) { publishesTbar = [ { xtype: 'component', html: 'Publishes:   ' + Ext.Object.getKeys(publishes).join(' • ') + '' } ]; } me.bindingsGrid = { xtype: 'gridpanel', title: title += comp.id, header: { items: [ { xtype: 'button', text: 'Open in dedicated tab', ui: 'default-toolbar', handler: function(btn) { btn.up('bindinspector-container').onComponentDblclick(null, comp); } } ] }, region: 'center', cls: Ext.baseCSSPrefix + 'bindinspector-compdetail-grid', flex: 1, hideHeaders: true, store: { model: me.BindingModel, data: bindData }, columns: [ { flex: 1, scope: me, renderer: me.bindingRenderer } ], tbar: publishesTbar, bbar: [ { xtype: 'checkboxfield', itemId: 'highlightToggle', boxLabel: 'Highlight VM target nodes on binding selection', checked: true, listeners: { scope: me, change: me.onHighlightChange } } ], viewConfig: { stripeRows: false, trackOver: false, getRowClass: function(record, index, rowParams, store) { var cls = []; if (index === store.getCount() - 1) { cls.push(me.lastItemCls); } return cls.join(' '); } }, listeners: { scope: me, cellclick: me.onCellClick, selectionchange: me.onSelectionChange } }; me.viewModelTree = { xtype: 'bindinspector-viewmodeldetail', itemId: 'vm-' + vm.id, vm: vm, region: 'east', split: true, width: '50%', height: '50%' }; me.items = []; me.items.push(bindings ? me.bindingsGrid : me.bindingsPreviewDefault); me.items.push(vm ? me.viewModelTree : me.vmPreviewDefault); me.callParent(arguments); }, bindingRenderer: function(v, meta, rec) { var me = this, binding = rec.get('binding'), key = rec.get('key'), descriptor = me.descriptorRenderer(rec.get('descriptor'), meta, rec), value = Ext.app.bindinspector.Util.valueRenderer(rec.get('value')), bindingType = 'Direct'; if (Ext.isEmpty(value) || value === 'null') { value = 'No value found'; } key = '' + key + ': '; descriptor = '' + descriptor + ''; value = '' + value + ''; if (binding.isTemplateBinding) { bindingType = 'Template'; } else if (binding.isMultiBinding) { bindingType = 'Multi'; } bindingType = Ext.util.Format.format('
{0}
', bindingType); return key + descriptor + '
' + value + bindingType; }, onHighlightChange: function(field) { var compDetail = this.down('gridpanel'), selModel = compDetail.getSelectionModel(); if (!field.checked) { this.onSelectionChange(selModel, null, true); } else { this.onSelectionChange(selModel, selModel.getSelection()); } }, onSelectionChange: function(selModel, selected, clear) { var vmDetail = this.down('bindinspector-viewmodeldetail'), store = vmDetail.getStore(), tokens, binding, highlight, root, targets, highlighted; if ((selected && selected.length === 0) || clear === true) { store.suspendEvents(); vmDetail.getStore().getRootNode().cascadeBy({ before: function(node) { node.set('highlighted', false); } }); store.resumeEvents(); vmDetail.getView().refresh(); return; } selected = selected[0]; tokens = selected.get('tokens'); binding = selected.get('binding'); highlight = this.down('#highlightToggle').checked; store = vmDetail.getStore(); root = store.getRootNode(); targets = []; if (tokens && highlight) { if (binding.isTemplateBinding) { Ext.Array.forEach(tokens, function(token) { targets.push(root.findChild('name', token[0])); }, this); } else if (binding.isMultiBinding) {} else { targets.push(root.findChild('name', tokens[0])); } } store.suspendEvents(); root.cascadeBy({ before: function(node) { highlighted = targets.length === 0; Ext.Array.forEach(targets, function(target) { if (node === target || node.isAncestor(target)) { highlighted = true; } }); node.set('highlighted', highlighted || -1); } }); store.resumeEvents(); vmDetail.getView().refresh(); vmDetail.getSelectionModel().select(targets[0]); }, onCellClick: function(view, cell, colIdx, record, row, rowIdx, e) { var target = e.getTarget('.' + this.activeCls), path; if (target) { path = target.getAttribute('data-path'); this.showPath(path); } }, showPath: function(path) { this.selectPath(this.down('bindinspector-viewmodeldetail'), path); }, selectPath: function(tab, path) { var node = tab.getRootNode(), parts = path.split('.'), len = parts.length, i; for (i = 0; node && i < len; ++i) { node = this.getChildByKey(node, parts[i]); } if (node) { tab.getSelectionModel().select(node); } }, getChildByKey: function(node, key) { var childNodes = node.childNodes; if (childNodes) { return Ext.Array.findBy(childNodes, function(child) { return child.get('name') === key; }); } return null; }, descriptorRenderer: function(v, meta, rec) { var binding = rec.get('binding'), descriptor = rec.get('descriptor'), tokens = rec.get('tokens'); v = v || ''; if (binding.isTemplateBinding) { Ext.Array.forEach(tokens, function(token) { var tokenRe = new RegExp('{' + token.join('\\.') + '}', 'g'); v = v.replace(tokenRe, this.parseTokens(token)); }, this); } else if (binding.isMultiBinding) {} else { return v.replace(descriptor, this.parseTokens(tokens)); } return Ext.String.htmlEncode(v); }, parseTokens: function(tokens) { var me = this, out = [], vm = me.env.getInheritedVM(me.component), currPath = '', currParent = vm.rootStub, direct = false, inherited = false, addlCls = '', tip = '', baseToken = '', ownerVMs, len, vmPlural; tokens = tokens || []; Ext.Array.forEach(tokens, function(token) { var stub = Ext.app.bindinspector.Util.getChildStub(token, currParent), cls = '', value; if (stub) { value = stub.value; if (value !== undefined) { cls = me.activeCls; } } else {} out.push('' + token + ''); currPath += token + '.'; currParent = stub; }, me); if (tokens[0]) { baseToken = tokens[0]; ownerVMs = vm.dataMap[tokens[0]].ownerVMs; len = ownerVMs.length; Ext.Array.forEach(ownerVMs, function(v) { if (v.id === vm.id) { direct = true; } if (v.id !== vm.id) { inherited = true; } }); } if (direct && inherited) { addlCls += ' ' + me.multipleCls; vmPlural = len > 1 ? 'VMs' : 'VM'; tip = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + baseToken + '  provided by this VM and ' + (len - 1) + ' ancestor ' + vmPlural + '"'; } else if (direct) { addlCls += ' ' + me.directCls; tip = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + baseToken + '  is provided by this VM"'; } else if (inherited) { addlCls += ' ' + me.inheritedCls; vmPlural = len > 1 ? 'VMs' : 'VM'; tip = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + baseToken + '  is provided by ' + len + ' ancestor ' + vmPlural + '"'; } return '{' + out.join('.') + '}'; } }, function() { this.prototype.BindingModel = Ext.define(null, { extend: 'Ext.data.Model', fields: [ 'key', 'descriptor', 'tokens', 'value', 'binding' ] }); }); Ext.define('Ext.tree.View', { extend: 'Ext.view.Table', alias: 'widget.treeview', config: { selectionModel: { type: 'treemodel' } }, isTreeView: true, loadingCls: Ext.baseCSSPrefix + 'grid-tree-loading', expandedCls: Ext.baseCSSPrefix + 'grid-tree-node-expanded', leafCls: Ext.baseCSSPrefix + 'grid-tree-node-leaf', expanderSelector: '.' + Ext.baseCSSPrefix + 'tree-expander', checkboxSelector: '.' + Ext.baseCSSPrefix + 'tree-checkbox', expanderIconOverCls: Ext.baseCSSPrefix + 'tree-expander-over', nodeAnimWrapCls: Ext.baseCSSPrefix + 'tree-animator-wrap', ariaRole: 'tree', loadMask: false, rootVisible: true, expandDuration: 250, collapseDuration: 250, toggleOnDblClick: true, stripeRows: false, uiFields: { checked: 1, icon: 1, iconCls: 1 }, rowFields: { expanded: 1, loaded: 1, expandable: 1, leaf: 1, loading: 1, qtip: 1, qtitle: 1, cls: 1 }, treeRowTpl: [ '{%', 'this.processRowValues(values);', 'this.nextTpl.applyOut(values, out, parent);', '%}', { priority: 10, processRowValues: function(rowValues) { var record = rowValues.record, view = rowValues.view; rowValues.rowAttr['data-qtip'] = record.get('qtip') || ''; rowValues.rowAttr['data-qtitle'] = record.get('qtitle') || ''; if (record.isExpanded()) { rowValues.rowClasses.push(view.expandedCls); } if (record.isLeaf()) { rowValues.rowClasses.push(view.leafCls); } if (record.isLoading()) { rowValues.rowClasses.push(view.loadingCls); } } } ], initComponent: function() { var me = this; if (me.bufferedRenderer) { me.animate = false; } else if (me.initialConfig.animate === undefined) { me.animate = Ext.enableFx; } me.store = me.panel.getStore(); me.onRootChange(me.store.getRoot()); me.animQueue = {}; me.animWraps = {}; me.callParent(); me.store.setRootVisible(me.rootVisible); me.addRowTpl(Ext.XTemplate.getTpl(me, 'treeRowTpl')); }, onFillComplete: function(treeStore, fillRoot, newNodes) { var me = this, store = me.store, start = store.indexOf(newNodes[0]); fillRoot.triggerUIUpdate(); if (!newNodes.length || start === -1) { return; } me.onAdd(me.store, newNodes, start); me.refreshPartner(); }, refreshPartner: function() { var partner = this.lockingPartner; if (partner) { partner.refresh(); } }, afterRender: function() { var me = this; me.callParent(); me.el.on({ scope: me, delegate: me.expanderSelector, mouseover: me.onExpanderMouseOver, mouseout: me.onExpanderMouseOut, click: { delegate: me.checkboxSelector, fn: me.onCheckboxChange, scope: me } }); }, afterComponentLayout: function(width, height, prevWidth, prevHeight) { var scroller = this.getScrollable(); this.callParent([ width, height, prevWidth, prevHeight ]); if (scroller && !this.bufferedRenderer) { scroller.refresh(); } }, processUIEvent: function(e) { if (e.getTarget('.' + this.nodeAnimWrapCls, this.el)) { return false; } return this.callParent([ e ]); }, setRootNode: function(node) { this.node = node; }, onCheckboxChange: function(e, t) { var me = this, item = e.getTarget(me.getItemSelector(), me.getTargetEl()); if (item) { me.onCheckChange(me.getRecord(item)); } }, onCheckChange: function(record) { var checked = record.get('checked'); if (Ext.isBoolean(checked)) { checked = !checked; record.set('checked', checked); this.fireEvent('checkchange', record, checked); } }, getChecked: function() { var checked = []; this.node.cascadeBy(function(rec) { if (rec.get('checked')) { checked.push(rec); } }); return checked; }, isItemChecked: function(rec) { return rec.get('checked'); }, createAnimWrap: function(record, index) { var me = this, node = me.getNode(record), tmpEl; tmpEl = Ext.fly(node).insertSibling({ role: 'presentation', tag: 'div', cls: me.nodeAnimWrapCls }, 'after'); return { record: record, node: node, el: tmpEl, expanding: false, collapsing: false, animateEl: tmpEl, targetEl: tmpEl }; }, getAnimWrap: function(parent, bubble) { if (!this.animate) { return null; } var wraps = this.animWraps, wrap = wraps[parent.internalId]; if (bubble !== false) { while (!wrap && parent) { parent = parent.parentNode; if (parent) { wrap = wraps[parent.internalId]; } } } return wrap; }, doAdd: function(records, index) { var me = this, record = records[0], parent = record.parentNode, all = me.all, relativeIndex, animWrap = me.getAnimWrap(parent), targetEl, childNodes, len, result, children; if (!animWrap || !animWrap.expanding) { return me.callParent([ records, index ]); } result = me.bufferRender(records, index, true); children = result.children; parent = animWrap.record; targetEl = animWrap.targetEl; childNodes = targetEl.dom.childNodes; len = childNodes.length; relativeIndex = index - me.indexInStore(parent) - 1; if (!len || relativeIndex >= len) { targetEl.appendChild(result.fragment, true); } else { Ext.fly(childNodes[relativeIndex]).insertSibling(children, 'before', true); } all.insert(index, children); return children; }, onRemove: function(ds, records, index) { var me = this, empty, i; if (me.viewReady) { empty = me.store.getCount() === 0; if (me.bufferedRenderer) { return me.callParent([ ds, records, index ]); } if (empty) { me.refresh(); } else { for (i = records.length - 1 , index += i; i >= 0; --i , --index) { me.doRemove(records[i], index); } me.refreshSizePending = true; } if (me.hasListeners.itemremove) { for (i = records.length - 1 , index += i; i >= 0; --i , --index) { me.fireEvent('itemremove', records[i], index, me); } } } }, doRemove: function(record, index) { var me = this, all = me.all, animWrap = me.getAnimWrap(record), item = all.item(index), node = item ? item.dom : null; if (!node || !animWrap || !animWrap.collapsing) { return me.callParent([ record, index ]); } animWrap.targetEl.dom.insertBefore(node, animWrap.targetEl.dom.firstChild); all.removeElement(index); }, onBeforeExpand: function(parent, records, index) { var me = this, animWrap; if (me.rendered && me.all.getCount() && me.animate) { if (me.getNode(parent)) { animWrap = me.getAnimWrap(parent, false); if (!animWrap) { animWrap = me.animWraps[parent.internalId] = me.createAnimWrap(parent); animWrap.animateEl.setHeight(0); } else if (animWrap.collapsing) { animWrap.targetEl.select(me.itemSelector).destroy(); } animWrap.expanding = true; animWrap.collapsing = false; } } }, onExpand: function(parent) { var me = this, queue = me.animQueue, id = parent.getId(), node = me.getNode(parent), index = node ? me.indexOf(node) : -1, animWrap, animateEl, targetEl; if (me.singleExpand) { me.ensureSingleExpand(parent); } if (index === -1) { return; } animWrap = me.getAnimWrap(parent, false); if (!animWrap) { parent.isExpandingOrCollapsing = false; me.fireEvent('afteritemexpand', parent, index, node); return; } animateEl = animWrap.animateEl; targetEl = animWrap.targetEl; animateEl.stopAnimation(); queue[id] = true; Ext.on('idle', function() { animateEl.dom.style.height = '0px'; }, null, { single: true }); animateEl.animate({ from: { height: 0 }, to: { height: targetEl.dom.scrollHeight }, duration: me.expandDuration, listeners: { afteranimate: function() { var items = targetEl.dom.childNodes, activeEl = Ext.Element.getActiveElement(); if (items.length) { if (!targetEl.contains(activeEl)) { activeEl = null; } animWrap.el.insertSibling(items, 'before', true); if (activeEl) { activeEl.focus(); } } animWrap.el.destroy(); me.animWraps[animWrap.record.internalId] = queue[id] = null; } }, callback: function() { parent.isExpandingOrCollapsing = false; if (!me.isDestroyed) { me.refreshSize(true); } me.fireEvent('afteritemexpand', parent, index, node); } }); }, onBeforeCollapse: function(parent, records, index, callback, scope) { var me = this, animWrap; if (me.rendered && me.all.getCount()) { if (me.animate) { if (parent.isVisible()) { animWrap = me.getAnimWrap(parent); if (!animWrap) { animWrap = me.animWraps[parent.internalId] = me.createAnimWrap(parent, index); } else if (animWrap.expanding) { animWrap.targetEl.select(this.itemSelector).destroy(); } animWrap.expanding = false; animWrap.collapsing = true; animWrap.callback = callback; animWrap.scope = scope; } } else { me.onCollapseCallback = callback; me.onCollapseScope = scope; } } }, onCollapse: function(parent) { var me = this, queue = me.animQueue, id = parent.getId(), node = me.getNode(parent), index = node ? me.indexOf(node) : -1, animWrap = me.getAnimWrap(parent), animateEl; if (!me.all.getCount() || !parent.isVisible()) { return; } if (!animWrap) { parent.isExpandingOrCollapsing = false; me.fireEvent('afteritemcollapse', parent, index, node); Ext.callback(me.onCollapseCallback, me.onCollapseScope); me.onCollapseCallback = me.onCollapseScope = null; return; } animateEl = animWrap.animateEl; queue[id] = true; animateEl.stopAnimation(); animateEl.animate({ to: { height: 0 }, duration: me.collapseDuration, listeners: { afteranimate: function() { animWrap.el.destroy(); me.animWraps[animWrap.record.internalId] = queue[id] = null; } }, callback: function() { parent.isExpandingOrCollapsing = false; if (!me.isDestroyed) { me.refreshSize(true); } me.fireEvent('afteritemcollapse', parent, index, node); Ext.callback(animWrap.callback, animWrap.scope); animWrap.callback = animWrap.scope = null; } }); }, isAnimating: function(node) { return !!this.animQueue[node.getId()]; }, expand: function(record, deep, callback, scope) { var me = this, doAnimate = !!me.animate, result; if (!doAnimate || !record.isExpandingOrCollapsing) { if (!record.isLeaf()) { record.isExpandingOrCollapsing = doAnimate; } Ext.suspendLayouts(); result = record.expand(deep, callback, scope); Ext.resumeLayouts(true); return result; } }, collapse: function(record, deep, callback, scope) { var me = this, doAnimate = !!me.animate; if (!doAnimate || !record.isExpandingOrCollapsing) { if (!record.isLeaf()) { record.isExpandingOrCollapsing = doAnimate; } return record.collapse(deep, callback, scope); } }, toggle: function(record, deep, callback, scope) { if (record.isExpanded()) { this.collapse(record, deep, callback, scope); } else { this.expand(record, deep, callback, scope); } }, onItemDblClick: function(record, item, index, e) { var me = this, editingPlugin = me.editingPlugin; me.callParent([ record, item, index, e ]); if (me.toggleOnDblClick && record.isExpandable() && !(editingPlugin && editingPlugin.clicksToEdit === 2)) { me.toggle(record); } }, onBeforeItemMouseDown: function(record, item, index, e) { if (e.getTarget(this.expanderSelector, item)) { return false; } return this.callParent([ record, item, index, e ]); }, onItemClick: function(record, item, index, e) { if (e.getTarget(this.expanderSelector, item) && record.isExpandable()) { this.toggle(record, e.ctrlKey); return false; } return this.callParent([ record, item, index, e ]); }, onExpanderMouseOver: function(e, t) { e.getTarget(this.cellSelector, 10, true).addCls(this.expanderIconOverCls); }, onExpanderMouseOut: function(e, t) { e.getTarget(this.cellSelector, 10, true).removeCls(this.expanderIconOverCls); }, getStoreListeners: function() { return Ext.apply(this.callParent(), { rootchange: this.onRootChange, fillcomplete: this.onFillComplete }); }, onBindStore: function(store, initial, propName, oldStore) { var oldRoot = oldStore && oldStore.getRootNode(), newRoot = store && store.getRootNode(); this.callParent([ store, initial, propName, oldStore ]); if (newRoot !== oldRoot) { this.onRootChange(newRoot, oldRoot); } }, onRootChange: function(newRoot, oldRoot) { var me = this; if (oldRoot) { me.rootListeners.destroy(); me.rootListeners = null; } if (newRoot) { me.rootListeners = newRoot.on({ beforeexpand: me.onBeforeExpand, expand: me.onExpand, beforecollapse: me.onBeforeCollapse, collapse: me.onCollapse, destroyable: true, scope: me }); } }, ensureSingleExpand: function(node) { var parent = node.parentNode; if (parent) { parent.eachChild(function(child) { if (child !== node && child.isExpanded()) { child.collapse(); } }); } }, shouldUpdateCell: function(record, column, changedFieldNames) { if (column.isTreeColumn && changedFieldNames) { var i = 0, len = changedFieldNames.length; for (; i < len; ++i) { if (this.rowFields[changedFieldNames[i]]) { return 1; } if (this.uiFields[changedFieldNames[i]]) { return 2; } } } return this.callParent([ record, column, changedFieldNames ]); } }); Ext.define('Ext.selection.RowModel', { extend: 'Ext.selection.DataViewModel', alias: 'selection.rowmodel', requires: [ 'Ext.grid.CellContext' ], enableKeyNav: true, isRowModel: true, deselectOnContainerClick: false, onUpdate: function(record) { var me = this, view = me.view, index; if (view && me.isSelected(record)) { index = view.indexOf(record); view.onRowSelect(index); if (record === me.lastFocused) { view.onRowFocus(index, true); } } }, onSelectChange: function(record, isSelected, suppressEvent, commitFn) { var me = this, views = me.views || [ me.view ], viewsLn = views.length, recordIndex = me.store.indexOf(record), eventName = isSelected ? 'select' : 'deselect', i, view; if ((suppressEvent || me.fireEvent('before' + eventName, me, record, recordIndex)) !== false && commitFn() !== false) { for (i = 0; i < viewsLn; i++) { view = views[i]; recordIndex = view.indexOf(record); if (view.indexOf(record) !== -1) { if (isSelected) { view.onRowSelect(recordIndex, suppressEvent); } else { view.onRowDeselect(recordIndex, suppressEvent); } } } if (!suppressEvent) { me.fireEvent(eventName, me, record, recordIndex); } } }, onEditorTab: function(editingPlugin, e) { var me = this, view = editingPlugin.context.view, record = editingPlugin.getActiveRecord(), position = editingPlugin.context, direction = e.shiftKey ? 'left' : 'right', lastPos; do { lastPos = position; position = view.walkCells(position, direction, e, me.preventWrap); if (lastPos && lastPos.isEqual(position)) { return; } } while ( position && (!position.column.getEditor(record) || !editingPlugin.startEditByPosition(position))); }, getCurrentPosition: function() { var firstSelection = this.selected.getAt(0); if (firstSelection) { return new Ext.grid.CellContext(this.view).setPosition(this.store.indexOf(firstSelection), 0); } }, selectByPosition: function(position, keepExisting) { if (!position.isCellContext) { position = new Ext.grid.CellContext(this.view).setPosition(position.row, position.column); } this.select(position.record, keepExisting); }, selectNext: function(keepExisting, suppressEvent) { var me = this, store = me.store, selection = me.getSelection(), record = selection[selection.length - 1], index = me.view.indexOf(record) + 1, success; if (index === store.getCount() || index === 0) { success = false; } else { me.doSelect(index, keepExisting, suppressEvent); success = true; } return success; }, selectPrevious: function(keepExisting, suppressEvent) { var me = this, selection = me.getSelection(), record = selection[0], index = me.view.indexOf(record) - 1, success; if (index < 0) { success = false; } else { me.doSelect(index, keepExisting, suppressEvent); success = true; } return success; }, isRowSelected: function(record) { return this.isSelected(record); }, isCellSelected: function(view, record, columnHeader) { return this.isSelected(record); } }); Ext.define('Ext.selection.TreeModel', { extend: 'Ext.selection.RowModel', alias: 'selection.treemodel', selectOnExpanderClick: false, constructor: function(config) { var me = this; me.callParent([ config ]); if (me.pruneRemoved) { me.pruneRemoved = false; me.pruneRemovedNodes = true; } }, getStoreListeners: function() { var me = this, result = me.callParent(); result.noderemove = me.onNodeRemove; return result; }, onNodeRemove: function(parent, node, isMove) { if (!isMove) { var toDeselect = []; this.gatherSelected(node, toDeselect); if (toDeselect.length) { this.deselect(toDeselect); } } }, pruneRemovedOnRefresh: function() { return this.pruneRemovedNodes; }, vetoSelection: function(e) { var view = this.view, select = this.selectOnExpanderClick, veto = !select && e.type === 'click' && e.getTarget(view.expanderSelector || (view.lockingPartner && view.lockingPartner.expanderSelector)); return veto || this.callParent([ e ]); }, privates: { gatherSelected: function(node, toDeselect) { var childNodes = node.childNodes, i, len, child; if (this.selected.containsKey(node.id)) { toDeselect.push(node); } if (childNodes) { for (i = 0 , len = childNodes.length; i < len; ++i) { child = childNodes[i]; this.gatherSelected(child, toDeselect); } } } } }); Ext.define('Ext.grid.ColumnLayout', { extend: 'Ext.layout.container.HBox', alias: 'layout.gridcolumn', type: 'gridcolumn', requires: [ 'Ext.panel.Table' ], firstHeaderCls: Ext.baseCSSPrefix + 'column-header-first', lastHeaderCls: Ext.baseCSSPrefix + 'column-header-last', initLayout: function() { this.callParent(); if (this.scrollbarWidth === undefined) { this.self.prototype.scrollbarWidth = Ext.getScrollbarSize().width; } }, beginLayout: function(ownerContext) { var me = this, owner = me.owner, view = owner.grid ? owner.grid.getView() : null, firstCls = me.firstHeaderCls, lastCls = me.lastHeaderCls, bothCls = [ firstCls, lastCls ], items = me.getVisibleItems(), len = items.length, i, item; if (view && view.scrollFlags.x) { me.viewScrollX = view.getScrollX(); owner.suspendEvent('scroll'); view.suspendEvent('scroll'); } me.callParent([ ownerContext ]); for (i = 0; i < len; i++) { item = items[i]; if (len === 1) { item.addCls(bothCls); } else if (i === 0) { item.addCls(firstCls); item.removeCls(lastCls); } else if (i === len - 1) { item.removeCls(firstCls); item.addCls(lastCls); } else { item.removeCls(bothCls); } } me.scrollbarWidth = 0; if (owner.isRootHeader) { me.determineScrollbarWidth(ownerContext); } if (!me.scrollbarWidth) { ownerContext.manageScrollbar = false; } }, moveItemBefore: function(item, before) { var prevOwner = item.ownerCt; if (item !== before && prevOwner) { prevOwner.remove(item, false); } return this.callParent([ item, before ]); }, determineScrollbarWidth: function(ownerContext) { var me = this, owner = me.owner, grid = owner.grid, vetoReserveScrollbar = owner.reserveScrollbar === false, reserveScrollbar = grid.reserveScrollbar && !vetoReserveScrollbar, manageScrollbar = !reserveScrollbar && !vetoReserveScrollbar && grid.view.scrollFlags.y; ownerContext.manageScrollbar = manageScrollbar; if (!grid.ownerGrid.collapsed && (reserveScrollbar || manageScrollbar)) { delete me.scrollbarWidth; } }, calculate: function(ownerContext) { var me = this, grid = me.owner.grid, viewContext = ownerContext.viewContext, state = ownerContext.state, context = ownerContext.context, lockingPartnerContext, ownerGrid, columnsChanged, columns, len, i, column, scrollbarAdjustment, viewOverflowY; me.callParent([ ownerContext ]); if (grid && state.parallelDone) { lockingPartnerContext = viewContext.lockingPartnerContext; ownerGrid = grid.ownerGrid; if (ownerGrid.forceFit && !state.reflexed) { if (me.convertWidthsToFlexes(ownerContext)) { me.cacheFlexes(ownerContext); me.done = false; ownerContext.invalidate({ state: { reflexed: true, scrollbarAdjustment: me.getScrollbarAdjustment(ownerContext) } }); return; } } if ((columnsChanged = state.columnsChanged) === undefined) { columns = ownerContext.target.getVisibleGridColumns(); columnsChanged = false; for (i = 0 , len = columns.length; i < len; i++) { column = context.getCmp(columns[i]); if (!column.lastBox || column.props.width !== column.lastBox.width) { (columnsChanged || (columnsChanged = []))[i] = column; } } state.columnsChanged = columnsChanged; ownerContext.setProp('columnsChanged', columnsChanged); } if (ownerContext.manageScrollbar) { scrollbarAdjustment = me.getScrollbarAdjustment(ownerContext); if (scrollbarAdjustment) { viewOverflowY = viewContext.getProp('viewOverflowY'); if (viewOverflowY === undefined) { me.done = false; return; } if (!viewOverflowY) { if (lockingPartnerContext) { lockingPartnerContext.invalidate(); lockingPartnerContext.headerContext.invalidate(); } viewContext.invalidate(); ownerContext.invalidate({ state: { scrollbarAdjustment: 0 } }); } } } } }, finishedLayout: function(ownerContext) { var me = this, owner = me.owner, view = owner.grid ? owner.grid.getView() : null, viewScrollX = me.viewScrollX; me.callParent([ ownerContext ]); if (view && view.scrollFlags.x) { if (viewScrollX !== undefined && owner.tooNarrow && owner.componentLayoutCounter) { owner.setScrollX(viewScrollX); } view.resumeEvent('scroll'); owner.resumeEvent('scroll'); } }, convertWidthsToFlexes: function(ownerContext) { var me = this, totalWidth = 0, calculated = me.sizeModels.calculated, childItems, len, i, childContext, item; childItems = ownerContext.childItems; len = childItems.length; for (i = 0; i < len; i++) { childContext = childItems[i]; item = childContext.target; totalWidth += childContext.props.width; if (!(item.fixed || item.resizable === false)) { item.flex = ownerContext.childItems[i].flex = childContext.props.width; item.width = null; childContext.widthModel = calculated; } } return totalWidth !== ownerContext.props.width; }, getScrollbarAdjustment: function(ownerContext) { var me = this, state = ownerContext.state, grid = me.owner.grid, scrollbarAdjustment = state.scrollbarAdjustment; if (scrollbarAdjustment === undefined) { scrollbarAdjustment = 0; if (grid.reserveScrollbar || (ownerContext.manageScrollbar && !grid.ownerGrid.layout.ownerContext.heightModel.shrinkWrap)) { scrollbarAdjustment = me.scrollbarWidth; } state.scrollbarAdjustment = scrollbarAdjustment; } return scrollbarAdjustment; }, getContainerSize: function(ownerContext) { var me = this, got, needed, padding, gotWidth, gotHeight, width, height, result; if (me.owner.isRootHeader) { result = me.callParent([ ownerContext ]); if (result.gotWidth) { result.width -= me.getScrollbarAdjustment(ownerContext); } } else { padding = ownerContext.paddingContext.getPaddingInfo(); got = needed = 0; if (!ownerContext.widthModel.shrinkWrap) { ++needed; width = ownerContext.getProp('innerWidth'); gotWidth = (typeof width === 'number'); if (gotWidth) { ++got; width -= padding.width; if (width < 0) { width = 0; } } } if (!ownerContext.heightModel.shrinkWrap) { ++needed; height = ownerContext.getProp('innerHeight'); gotHeight = (typeof height === 'number'); if (gotHeight) { ++got; height -= padding.height; if (height < 0) { height = 0; } } } return { width: width, height: height, needed: needed, got: got, gotAll: got === needed, gotWidth: gotWidth, gotHeight: gotHeight }; } return result; }, publishInnerCtSize: function(ownerContext) { var me = this, owner = me.owner, cw = ownerContext.peek('contentWidth'), adjustment = 0; if (cw != null && owner.isRootHeader) { adjustment = -ownerContext.state.scrollbarAdjustment; } return me.callParent([ ownerContext, adjustment ]); } }); Ext.define('Ext.dd.DragTracker', { uses: [ 'Ext.util.Region' ], mixins: { observable: 'Ext.util.Observable' }, active: false, trackOver: false, tolerance: 5, autoStart: false, constructor: function(config) { var me = this; Ext.apply(me, config); me.dragRegion = new Ext.util.Region(0, 0, 0, 0); if (me.el) { me.initEl(me.el); } me.mixins.observable.constructor.call(me); if (me.disabled) { me.disable(); } }, initEl: function(el) { var me = this, delegate = me.delegate; me.el = el = Ext.get(el); if (delegate && delegate.isElement) { me.handle = delegate; } me.delegate = me.handle ? undefined : me.delegate; if (!me.handle) { me.handle = el; } me.handleListeners = { scope: me, delegate: me.delegate, mousedown: me.onMouseDown, dragstart: me.onDragStart }; if (!Ext.supports.TouchEvents && (me.trackOver || me.overCls)) { Ext.apply(me.handleListeners, { mouseover: me.onMouseOver, mouseout: me.onMouseOut }); } me.mon(me.handle, me.handleListeners); me.keyNav = new Ext.util.KeyNav({ target: el, up: me.onResizeKeyDown, left: me.onResizeKeyDown, right: me.onResizeKeyDown, down: me.onResizeKeyDown, scope: me }); }, disable: function() { this.disabled = true; }, enable: function() { this.disabled = false; }, destroy: function() { var me = this; me.endDrag({}); me.clearListeners(); me.el = me.handle = null; }, onMouseOver: function(e, target) { var me = this, handleCls, el, i, len, cls; if (!me.disabled) { if (e.within(e.target, true, true) || me.delegate) { handleCls = me.handleCls; me.mouseIsOut = false; if (handleCls) { for (i = 0 , len = me.handleEls.length; i < len; i++) { el = me.handleEls[i]; cls = el.delegateCls; if (!cls) { cls = el.delegateCls = [ handleCls, '-', el.region, '-over' ].join(''); } el.addCls([ cls, me.overCls ]); } } me.fireEvent('mouseover', me, e, me.delegate ? e.getTarget(me.delegate, target) : me.handle); } } }, onMouseOut: function(e) { var me = this, el, i, len; if (me.mouseIsDown) { me.mouseIsOut = true; } else { if (me.handleCls) { for (i = 0 , len = me.handleEls.length; i < len; i++) { el = me.handleEls[i]; el.removeCls([ el.delegateCls, me.overCls ]); } } me.fireEvent('mouseout', me, e); } }, onMouseDown: function(e, target) { var me = this; if (me.disabled || e.dragTracked) { return; } me.dragTarget = me.delegate ? target : me.handle.dom; me.startXY = me.lastXY = e.getXY(); me.startRegion = Ext.fly(me.dragTarget).getRegion(); if (me.fireEvent('mousedown', me, e) === false || me.fireEvent('beforedragstart', me, e) === false || me.onBeforeStart(e) === false) { return; } me.mouseIsDown = true; e.dragTracked = true; me.el.setCapture(); e.stopPropagation(); if (me.preventDefault !== false) { e.preventDefault(); } Ext.getDoc().on({ scope: me, capture: true, mouseup: me.onMouseUp, mousemove: me.onMouseMove, selectstart: me.stopSelect }); me.dragEnded = false; if (!me.tolerance) { me.triggerStart(); } else if (me.autoStart) { me.timer = Ext.defer(me.triggerStart, me.autoStart === true ? 1000 : me.autoStart, me, [ e ]); } }, onMouseMove: function(e, target) { var me = this, xy = e.getXY(), s = me.startXY; e.stopPropagation(); if (me.preventDefault !== false) { e.preventDefault(); } if (me.dragEnded) { return; } me.lastXY = xy; if (!me.active) { if (Math.max(Math.abs(s[0] - xy[0]), Math.abs(s[1] - xy[1])) > me.tolerance) { me.triggerStart(e); } else { return; } } if (me.fireEvent('mousemove', me, e) === false) { me.onMouseUp(e); } else { me.onDrag(e); me.fireEvent('drag', me, e); } }, onMouseUp: function(e) { var me = this; me.mouseIsDown = false; if (me.mouseIsOut) { me.mouseIsOut = false; me.onMouseOut(e); } if (me.preventDefault !== false) { e.preventDefault(); } if (Ext.isIE && document.releaseCapture) { document.releaseCapture(); } me.fireEvent('mouseup', me, e); me.endDrag(e); }, endDrag: function(e) { var me = this, wasActive = me.active; Ext.getDoc().un({ mousemove: me.onMouseMove, mouseup: me.onMouseUp, selectstart: me.stopSelect, capture: true, scope: me }); me.clearStart(); me.active = false; if (wasActive) { me.dragEnded = true; me.onEnd(e); me.fireEvent('dragend', me, e); } me._constrainRegion = null; }, triggerStart: function(e) { var me = this; me.clearStart(); me.active = true; me.onStart(e); me.fireEvent('dragstart', me, e); }, clearStart: function() { var timer = this.timer; if (timer) { clearTimeout(timer); this.timer = null; } }, stopSelect: function(e) { e.stopEvent(); return false; }, onBeforeStart: function(e) {}, onStart: function(xy) {}, onDrag: function(e) {}, onEnd: function(e) {}, getDragTarget: function() { return this.dragTarget; }, getDragCt: function() { return this.el; }, getConstrainRegion: function() { var me = this; if (me.constrainTo) { if (me.constrainTo instanceof Ext.util.Region) { return me.constrainTo; } if (!me._constrainRegion) { me._constrainRegion = Ext.fly(me.constrainTo).getViewRegion(); } } else { if (!me._constrainRegion) { me._constrainRegion = me.getDragCt().getViewRegion(); } } return me._constrainRegion; }, getXY: function(constrain) { return constrain ? this.constrainModes[constrain](this, this.lastXY) : this.lastXY; }, getOffset: function(constrain) { var xy = this.getXY(constrain), s = this.startXY; return [ xy[0] - s[0], xy[1] - s[1] ]; }, onDragStart: function(e) { e.stopPropagation(); }, constrainModes: { point: function(me, xy) { var dr = me.dragRegion, constrainTo = me.getConstrainRegion(); if (!constrainTo) { return xy; } dr.x = dr.left = dr[0] = dr.right = xy[0]; dr.y = dr.top = dr[1] = dr.bottom = xy[1]; dr.constrainTo(constrainTo); return [ dr.left, dr.top ]; }, dragTarget: function(me, xy) { var s = me.startXY, dr = me.startRegion.copy(), constrainTo = me.getConstrainRegion(), adjust; if (!constrainTo) { return xy; } dr.translateBy(xy[0] - s[0], xy[1] - s[1]); if (dr.right > constrainTo.right) { xy[0] += adjust = (constrainTo.right - dr.right); dr.left += adjust; } if (dr.left < constrainTo.left) { xy[0] += (constrainTo.left - dr.left); } if (dr.bottom > 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; } } }); Ext.define('Ext.grid.plugin.HeaderResizer', { extend: 'Ext.plugin.Abstract', requires: [ 'Ext.dd.DragTracker', 'Ext.util.Region' ], alias: 'plugin.gridheaderresizer', disabled: false, config: { dynamic: false }, colHeaderCls: Ext.baseCSSPrefix + 'column-header', minColWidth: 40, maxColWidth: 1000, eResizeCursor: 'col-resize', init: function(headerCt) { var me = this; me.headerCt = headerCt; headerCt.on('render', me.afterHeaderRender, me, { single: me }); if (!me.minColWidth) { me.self.prototype.minColWidth = Ext.grid.column.Column.prototype.minWidth; } }, destroy: function() { var tracker = this.tracker; if (tracker) { delete tracker.onBeforeStart; delete tracker.onStart; delete tracker.onDrag; delete tracker.onEnd; tracker.destroy(); this.tracker = null; } }, afterHeaderRender: function() { var me = this, headerCt = me.headerCt, el = headerCt.el; headerCt.mon(el, 'mousemove', me.onHeaderCtMouseMove, me); me.markerOwner = me.ownerGrid = me.headerCt.up('tablepanel'); if (me.markerOwner.ownerLockable) { me.markerOwner = me.markerOwner.ownerLockable; } me.tracker = new Ext.dd.DragTracker({ disabled: me.disabled, onBeforeStart: me.onBeforeStart.bind(me), onStart: me.onStart.bind(me), onDrag: me.onDrag.bind(me), onEnd: me.onEnd.bind(me), tolerance: 3, autoStart: 300, el: el }); }, onHeaderCtMouseMove: function(e) { var me = this; if (me.headerCt.dragging || me.disabled) { if (me.activeHd) { me.activeHd.el.dom.style.cursor = ''; delete me.activeHd; } } else { me.findActiveHeader(e); } }, findActiveHeader: function(e) { var me = this, headerEl = e.getTarget('.' + me.colHeaderCls, 3, true), ownerGrid = me.ownerGrid, ownerLockable = ownerGrid.ownerLockable, overHeader, resizeHeader, headers, header; if (headerEl) { overHeader = Ext.getCmp(headerEl.id); if (overHeader.isAtEndEdge(e)) { if (me.headerCt.visibleColumnManager.getColumns().length === 1 && me.headerCt.forceFit) { return; } resizeHeader = overHeader; } else if (overHeader.isAtStartEdge(e)) { headers = me.headerCt.visibleColumnManager.getColumns(); header = overHeader.isGroupHeader ? overHeader.getGridColumns()[0] : overHeader; resizeHeader = headers[Ext.Array.indexOf(headers, header) - 1]; if (!resizeHeader && ownerLockable && !ownerGrid.isLocked) { headers = ownerLockable.lockedGrid.headerCt.visibleColumnManager.getColumns(); resizeHeader = headers[headers.length - 1]; } } if (resizeHeader) { if (resizeHeader.isGroupHeader) { headers = resizeHeader.getGridColumns(); resizeHeader = headers[headers.length - 1]; } if (resizeHeader && !(resizeHeader.fixed || (resizeHeader.resizable === false))) { me.activeHd = resizeHeader; overHeader.el.dom.style.cursor = me.eResizeCursor; if (overHeader.triggerEl) { overHeader.triggerEl.dom.style.cursor = me.eResizeCursor; } } } else { overHeader.el.dom.style.cursor = ''; if (overHeader.triggerEl) { overHeader.triggerEl.dom.style.cursor = ''; } me.activeHd = null; } } return me.activeHd; }, onBeforeStart: function(e) { var me = this; me.dragHd = Ext.supports.Touch ? me.findActiveHeader(e) : me.activeHd; if (!!me.dragHd && !me.headerCt.dragging) { me.xDelta = me.dragHd.getX() + me.dragHd.getWidth() - me.tracker.getXY()[0]; me.tracker.constrainTo = me.getConstrainRegion(); return true; } else { me.headerCt.dragging = false; return false; } }, getConstrainRegion: function() { var me = this, dragHdEl = me.dragHd.el, nextHd, ownerGrid = me.ownerGrid, widthModel = ownerGrid.getSizeModel().width, maxColWidth = widthModel.shrinkWrap ? me.headerCt.getWidth() - me.headerCt.visibleColumnManager.getColumns().length * me.minColWidth : me.maxColWidth, result; if (me.headerCt.forceFit) { nextHd = me.dragHd.nextNode('gridcolumn:not([hidden]):not([isGroupHeader])'); if (nextHd && me.headerInSameGrid(nextHd)) { maxColWidth = dragHdEl.getWidth() + (nextHd.getWidth() - me.minColWidth); } } else if (ownerGrid.isLocked && widthModel.shrinkWrap) { maxColWidth = me.dragHd.up('[scrollerOwner]').getTargetEl().getWidth(true) - ownerGrid.getWidth() - (ownerGrid.ownerLockable.normalGrid.visibleColumnManager.getColumns().length * me.minColWidth + Ext.getScrollbarSize().width); } result = me.adjustConstrainRegion(dragHdEl.getRegion(), 0, 0, 0, me.minColWidth); result.right = dragHdEl.getX() + maxColWidth; return result; }, onStart: function(e) { var me = this, dragHd = me.dragHd, width = dragHd.el.getWidth(), headerCt = dragHd.getRootHeaderCt(), x, y, markerOwner, lhsMarker, rhsMarker, markerHeight; me.headerCt.dragging = true; me.origWidth = width; if (!me.dynamic) { markerOwner = me.markerOwner; if (markerOwner.frame && markerOwner.resizable) { me.gridOverflowSetting = markerOwner.el.dom.style.overflow; markerOwner.el.dom.style.overflow = 'hidden'; } x = me.getLeftMarkerX(markerOwner); lhsMarker = markerOwner.getLhsMarker(); rhsMarker = markerOwner.getRhsMarker(); markerHeight = me.ownerGrid.body.getHeight() + headerCt.getHeight(); y = headerCt.getOffsetsTo(markerOwner)[1] - markerOwner.el.getBorderWidth('t'); lhsMarker.setLocalY(y); rhsMarker.setLocalY(y); lhsMarker.setHeight(markerHeight); rhsMarker.setHeight(markerHeight); me.setMarkerX(lhsMarker, x); me.setMarkerX(rhsMarker, x + width); } }, onDrag: function(e) { var me = this; if (me.dynamic) { me.doResize(); } else { me.setMarkerX(me.getMovingMarker(me.markerOwner), me.calculateDragX(me.markerOwner)); } }, getMovingMarker: function(markerOwner) { return markerOwner.getRhsMarker(); }, onEnd: function(e) { var me = this, markerOwner; me.headerCt.dragging = false; if (me.dragHd) { if (!me.dynamic) { markerOwner = me.headerCt.up('tablepanel'); if (markerOwner.ownerLockable) { markerOwner = markerOwner.ownerLockable; } if ('gridOverflowSetting' in me) { markerOwner.el.dom.style.overflow = me.gridOverflowSetting; } me.setMarkerX(markerOwner.getLhsMarker(), -9999); me.setMarkerX(markerOwner.getRhsMarker(), -9999); } me.doResize(); } me.onHeaderCtMouseMove(e); }, doResize: function() { var me = this, dragHd = me.dragHd, nextHd, offset = me.tracker.getOffset('point'); if (dragHd && offset[0]) { if (dragHd.flex) { delete dragHd.flex; } Ext.suspendLayouts(); me.adjustColumnWidth(offset[0] - me.xDelta); if (me.headerCt.forceFit) { nextHd = dragHd.nextNode('gridcolumn:not([hidden]):not([isGroupHeader])'); if (nextHd && !me.headerInSameGrid(nextHd)) { nextHd = null; } if (nextHd) { delete nextHd.flex; nextHd.setWidth(nextHd.getWidth() - offset[0]); } } Ext.resumeLayouts(true); } }, headerInSameGrid: function(header) { var grid = this.dragHd.up('tablepanel'); return !!header.up(grid); }, disable: function() { var tracker = this.tracker; this.disabled = true; if (tracker) { tracker.disable(); } }, enable: function() { var tracker = this.tracker; this.disabled = false; if (tracker) { tracker.enable(); } }, calculateDragX: function(markerOwner) { return this.tracker.getXY('point')[0] + this.xDelta - markerOwner.getX() - markerOwner.el.getBorderWidth('l'); }, getLeftMarkerX: function(markerOwner) { return this.dragHd.getX() - markerOwner.getX() - markerOwner.el.getBorderWidth('l') - 1; }, setMarkerX: function(marker, x) { marker.setLocalX(x); }, adjustConstrainRegion: function(region, t, r, b, l) { return region.adjust(t, r, b, l); }, adjustColumnWidth: function(offsetX) { this.dragHd.setWidth(this.origWidth + offsetX); } }); Ext.define('Ext.dd.DragZone', { extend: 'Ext.dd.DragSource', constructor: function(el, config) { var me = this, scroll = me.containerScroll; me.callParent([ el, config ]); if (scroll) { el = me.scrollEl || el; el = Ext.get(el); if (Ext.isObject(scroll)) { el.ddScrollConfig = scroll; } Ext.dd.ScrollManager.register(el); } }, 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; }, getRepairXY: function(e) { return Ext.fly(this.dragData.ddel).getXY(); }, destroy: function() { this.callParent(); if (this.containerScroll) { Ext.dd.ScrollManager.unregister(this.scrollEl || this.el); } } }); Ext.define('Ext.grid.header.DragZone', { extend: 'Ext.dd.DragZone', colHeaderSelector: '.' + Ext.baseCSSPrefix + 'column-header', colInnerSelector: '.' + Ext.baseCSSPrefix + 'column-header-inner', maxProxyWidth: 120, constructor: function(headerCt) { var me = this; me.headerCt = headerCt; me.ddGroup = me.getDDGroup(); me.autoGroup = true; me.callParent([ headerCt.el ]); me.proxy.el.addCls(Ext.baseCSSPrefix + 'grid-col-dd'); }, getDDGroup: function() { return 'header-dd-zone-' + this.headerCt.up('[scrollerOwner]').id; }, getDragData: function(e) { if (e.getTarget(this.colInnerSelector)) { var header = e.getTarget(this.colHeaderSelector), headerCmp, ddel; if (header) { headerCmp = Ext.getCmp(header.id); if (!this.headerCt.dragging && headerCmp.draggable && !(headerCmp.isAtStartEdge(e) || headerCmp.isAtEndEdge(e))) { ddel = document.createElement('div'); ddel.role = 'presentation'; ddel.innerHTML = headerCmp.text; return { ddel: ddel, header: headerCmp }; } } } return false; }, onBeforeDrag: function() { return !(this.headerCt.dragging || this.disabled); }, onInitDrag: function() { this.headerCt.dragging = true; this.headerCt.hideMenu(); 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; }, enable: function() { this.disabled = false; } }); Ext.define('Ext.dd.DDTarget', { extend: 'Ext.dd.DragDrop', constructor: function(id, sGroup, config) { if (id) { this.initTarget(id, sGroup, config); } }, 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, toString: function() { return ("DDTarget " + this.id); } }); Ext.define('Ext.dd.ScrollManager', { singleton: true, requires: [ 'Ext.dd.DragDropManager' ], dirTrans: { up: -1, left: -1, down: 1, right: 1 }, 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 = this.doScroll.bind(this); this.ddmInstance = ddm; this.els = {}; this.dragEl = null; this.proc = {}; }, onStop: function(e) { var sm = Ext.dd.ScrollManager; sm.dragEl = null; sm.clearProc(); }, triggerRefresh: function() { if (this.ddmInstance.dragCurrent) { this.ddmInstance.refreshCache(this.ddmInstance.dragCurrent.groups); } }, doScroll: function() { var me = this; if (me.ddmInstance.dragCurrent) { var proc = me.proc, procEl = proc.el, scrollComponent = proc.component, ddScrollConfig = proc.el.ddScrollConfig, distance = ddScrollConfig && ddScrollConfig.increment ? ddScrollConfig.increment : me.increment, animate = ddScrollConfig && 'animate' in ddScrollConfig ? ddScrollConfig.animate : me.animate, afterScroll = function() { me.triggerRefresh(); }; if (animate) { if (animate === true) { animate = { callback: afterScroll }; } else { animate.callback = animate.callback ? Ext.Function.createSequence(animate.callback, afterScroll) : afterScroll; } } if (scrollComponent) { distance = distance * me.dirTrans[proc.dir]; if (proc.dir === 'up' || proc.dir === 'down') { scrollComponent.scrollBy(0, distance, animate); } else { scrollComponent.scrollBy(distance, 0, animate); } } else { procEl.scroll(proc.dir, distance, animate); } if (!animate) { afterScroll(); } } }, clearProc: function() { var proc = this.proc; if (proc.id) { clearInterval(proc.id); } proc.id = 0; proc.el = null; proc.dir = ""; }, startProc: function(el, dir) { var me = this, proc = me.proc, group, freq; me.clearProc(); proc.el = el; proc.dir = dir; group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined; freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) ? el.ddScrollConfig.frequency : me.frequency; if (group === undefined || me.ddmInstance.dragCurrent.ddGroup === group) { proc.id = Ext.interval(me.doScroll, freq); } }, onFire: function(e, isDrop) { var me = this, pt, proc, els, id, el, elementRegion, configSource; if (isDrop || !me.ddmInstance.dragCurrent) { return; } if (!me.dragEl || me.dragEl !== me.ddmInstance.dragCurrent) { me.dragEl = me.ddmInstance.dragCurrent; me.refreshCache(); } pt = e.getPoint(); proc = me.proc; els = me.els; for (id in els) { el = els[id]; elementRegion = el._region; configSource = el.ddScrollConfig || me; if (elementRegion && elementRegion.contains(pt) && el.isScrollable()) { if (elementRegion.bottom - pt.y <= configSource.vthresh) { if (proc.el !== el) { me.startProc(el, "down"); } return; } else if (elementRegion.right - pt.x <= configSource.hthresh) { if (proc.el !== el) { me.startProc(el, "right"); } return; } else if (pt.y - elementRegion.top <= configSource.vthresh) { if (proc.el !== el) { me.startProc(el, "up"); } return; } else if (pt.x - elementRegion.left <= configSource.hthresh) { if (proc.el !== el) { me.startProc(el, "left"); } return; } } } me.clearProc(); }, 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; } }, 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]; } }, vthresh: 25 * (window.devicePixelRatio || 1), hthresh: 25 * (window.devicePixelRatio || 1), increment: 100, frequency: 500, animate: true, animDuration: 0.4, ddGroup: undefined, refreshCache: function() { var els = this.els, id; for (id in els) { if (typeof els[id] === 'object') { els[id]._region = els[id].getRegion(); } } } }); Ext.define('Ext.dd.DropTarget', { extend: 'Ext.dd.DDTarget', requires: [ 'Ext.dd.ScrollManager' ], constructor: function(el, config) { this.el = Ext.get(el); Ext.apply(this, config); if (this.containerScroll) { Ext.dd.ScrollManager.register(this.el); } this.callParent([ this.el.dom, this.ddGroup || this.group, { isTarget: true } ]); }, containerScroll: false, dropAllowed: Ext.baseCSSPrefix + 'dd-drop-ok', dropNotAllowed: Ext.baseCSSPrefix + 'dd-drop-nodrop', isTarget: true, isNotifyTarget: true, notifyEnter: function(dd, e, data) { if (this.overClass) { this.el.addCls(this.overClass); } return this.dropAllowed; }, notifyOver: function(dd, e, data) { return this.dropAllowed; }, notifyOut: function(dd, e, data) { if (this.overClass) { this.el.removeCls(this.overClass); } }, notifyDrop: function(dd, e, data) { if (this.overClass) { this.el.removeCls(this.overClass); } return false; }, destroy: function() { this.callParent(); if (this.containerScroll) { Ext.dd.ScrollManager.unregister(this.el); } } }); 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, i, len; for (i = 0 , len = hs.length; i < len; i++) { this.handles[this.getId(hs[i])] = data; } } }, unregister: function(el) { var id = this.getId(el, false), data = this.elements[id], hs, i, len; if (data) { delete this.elements[id]; if (data.handles) { hs = data.handles; for (i = 0 , len = hs.length; i < len; i++) { delete this.handles[this.getId(hs[i], 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]; }, 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); }, onNodeEnter: function(n, dd, e, data) {}, onNodeOver: function(n, dd, e, data) { return this.dropAllowed; }, onNodeOut: function(n, dd, e, data) {}, onNodeDrop: function(n, dd, e, data) { return false; }, onContainerOver: function(dd, e, data) { return this.dropNotAllowed; }, onContainerDrop: function(dd, e, data) { return false; }, notifyEnter: function(dd, e, data) { return this.dropNotAllowed; }, notifyOver: function(dd, e, data) { var me = this, n = me.getTargetFromEvent(e); if (!n) { if (me.lastOverNode) { me.onNodeOut(me.lastOverNode, dd, e, data); me.lastOverNode = null; } return me.onContainerOver(dd, e, data); } if (me.lastOverNode !== n) { if (me.lastOverNode) { me.onNodeOut(me.lastOverNode, dd, e, data); } me.onNodeEnter(n, dd, e, data); me.lastOverNode = n; } return me.onNodeOver(n, dd, e, data); }, notifyOut: function(dd, e, data) { if (this.lastOverNode) { this.onNodeOut(this.lastOverNode, dd, e, data); this.lastOverNode = null; } }, notifyDrop: function(dd, e, data) { var me = this, n = me.getTargetFromEvent(e), result = n ? me.onNodeDrop(n, dd, e, data) : me.onContainerDrop(dd, e, data); if (me.lastOverNode) { me.onNodeOut(me.lastOverNode, dd, e, data); me.lastOverNode = null; } return result; }, triggerCacheRefresh: function() { Ext.dd.DDM.refreshCache(this.groups); } }); Ext.define('Ext.grid.header.DropZone', { extend: 'Ext.dd.DropZone', colHeaderCls: Ext.baseCSSPrefix + 'column-header', proxyOffsets: [ -4, -9 ], constructor: function(headerCt) { var me = this; me.headerCt = headerCt; me.ddGroup = me.getDDGroup(); me.autoGroup = true; me.callParent([ headerCt.el ]); }, destroy: function() { this.callParent(); Ext.destroy(this.topIndicator, this.bottomIndicator); }, getDDGroup: function() { return 'header-dd-zone-' + this.headerCt.up('[scrollerOwner]').id; }, getTargetFromEvent: function(e) { return e.getTarget('.' + this.colHeaderCls); }, getTopIndicator: function() { if (!this.topIndicator) { this.topIndicator = Ext.getBody().createChild({ role: 'presentation', cls: Ext.baseCSSPrefix + "col-move-top", "data-sticky": true, html: " " }); this.indicatorXOffset = Math.floor((this.topIndicator.dom.offsetWidth + 1) / 2); } return this.topIndicator; }, getBottomIndicator: function() { if (!this.bottomIndicator) { this.bottomIndicator = Ext.getBody().createChild({ role: 'presentation', cls: Ext.baseCSSPrefix + "col-move-bottom", "data-sticky": true, html: " " }); } return this.bottomIndicator; }, getLocation: function(e, t) { var x = e.getXY()[0], region = Ext.fly(t).getRegion(), pos; 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(data, node, e) { var me = this, dragHeader = data.header, dropLocation = me.getLocation(e, node), targetHeader = dropLocation.header, pos = dropLocation.pos, nextHd, prevHd, topIndicator, bottomIndicator, topAnchor, bottomAnchor, topXY, bottomXY, headerCtEl, minX, maxX, allDropZones, ln, i, dropZone; if (targetHeader === me.lastTargetHeader && pos === me.lastDropPos) { return; } nextHd = dragHeader.nextSibling('gridcolumn:not([hidden])'); prevHd = dragHeader.previousSibling('gridcolumn:not([hidden])'); me.lastTargetHeader = targetHeader; me.lastDropPos = pos; if (!targetHeader.draggable && pos === 'before' && targetHeader.getIndex() === 0) { return false; } data.dropLocation = dropLocation; if ((dragHeader !== targetHeader) && ((pos === "before" && nextHd !== targetHeader) || (pos === "after" && prevHd !== targetHeader)) && !targetHeader.isDescendantOf(dragHeader)) { allDropZones = Ext.dd.DragDropManager.getRelated(me); ln = allDropZones.length; i = 0; for (; i < ln; i++) { dropZone = allDropZones[i]; if (dropZone !== me && dropZone.invalidateDrop) { dropZone.invalidateDrop(); } } me.valid = true; topIndicator = me.getTopIndicator(); bottomIndicator = me.getBottomIndicator(); if (pos === 'before') { topAnchor = 'bc-tl'; bottomAnchor = 'tc-bl'; } else { topAnchor = 'bc-tr'; bottomAnchor = 'tc-br'; } topXY = topIndicator.getAlignToXY(targetHeader.el, topAnchor); bottomXY = bottomIndicator.getAlignToXY(targetHeader.el, bottomAnchor); headerCtEl = me.headerCt.el; minX = headerCtEl.getX() - me.indicatorXOffset; maxX = headerCtEl.getX() + headerCtEl.getWidth(); topXY[0] = Ext.Number.constrain(topXY[0], minX, maxX); bottomXY[0] = Ext.Number.constrain(bottomXY[0], minX, maxX); topIndicator.setXY(topXY); bottomIndicator.setXY(bottomXY); topIndicator.show(); bottomIndicator.show(); } else { me.invalidateDrop(); } }, invalidateDrop: function() { this.valid = false; this.hideIndicators(); }, onNodeOver: function(node, dragZone, e, data) { var me = this, from = data.header, doPosition, to, fromPanel, toPanel; if (data.header.el.dom === node) { doPosition = false; } else { data.isLock = data.isUnlock = data.crossPanel = false; to = me.getLocation(e, node).header; doPosition = (from.ownerCt === to.ownerCt); if (!doPosition && (!from.ownerCt.sealed && !to.ownerCt.sealed)) { doPosition = true; fromPanel = from.up('tablepanel'); toPanel = to.up('tablepanel'); if (fromPanel !== toPanel) { data.crossPanel = true; data.isLock = toPanel.isLocked && !fromPanel.isLocked; data.isUnlock = !toPanel.isLocked && fromPanel.isLocked; if ((data.isUnlock && from.lockable === false) || (data.isLock && !from.isLockable())) { doPosition = false; } } } } if (doPosition) { me.positionIndicator(data, node, e); } else { me.valid = false; } return me.valid ? me.dropAllowed : me.dropNotAllowed; }, hideIndicators: function() { var me = this; me.getTopIndicator().hide(); me.getBottomIndicator().hide(); me.lastTargetHeader = me.lastDropPos = null; }, onNodeOut: function() { this.hideIndicators(); }, getNestedHeader: function(header, first) { var items = header.items, pos; if (header.isGroupHeader && items.length) { pos = !first ? 'first' : 'last'; header = this.getNestedHeader(items[pos](), first); } return header; }, onNodeDrop: function(node, dragZone, e, data) { if (!this.valid) { return; } var me = this, dragHeader = data.header, dropLocation = data.dropLocation, dropPosition = dropLocation.pos, targetHeader = dropLocation.header, fromCt = dragHeader.ownerCt, fromCtRoot = fromCt.getRootHeaderCt(), toCt = targetHeader.ownerCt, visibleColumnManager = me.headerCt.visibleColumnManager, visibleFromIdx = visibleColumnManager.getHeaderIndex(dragHeader), visibleToIdx, colsToMove, moveMethod, scrollerOwner, savedWidth; if (data.isLock || data.isUnlock) { scrollerOwner = fromCt.up('[scrollerOwner]'); visibleToIdx = toCt.items.indexOf(targetHeader); if (dropPosition === 'after') { visibleToIdx++; } if (data.isLock) { scrollerOwner.lock(dragHeader, visibleToIdx, toCt); } else { scrollerOwner.unlock(dragHeader, visibleToIdx, toCt); } } else { visibleToIdx = dropPosition === 'after' ? visibleColumnManager.getHeaderIndex(me.getNestedHeader(targetHeader, 1)) + 1 : visibleColumnManager.getHeaderIndex(me.getNestedHeader(targetHeader, 0)); me.invalidateDrop(); savedWidth = dragHeader.getWidth(); Ext.suspendLayouts(); fromCt.isDDMoveInGrid = toCt.isDDMoveInGrid = !data.crossPanel; if (dragHeader.isGroupHeader && targetHeader.isGroupHeader) { dragHeader.setNestedParent(targetHeader); } if (dropPosition === 'before') { targetHeader.insertNestedHeader(dragHeader); } else { moveMethod = 'move' + dropPosition.charAt(0).toUpperCase() + dropPosition.substr(1); toCt[moveMethod](dragHeader, targetHeader); } if (visibleToIdx >= 0 && !(targetHeader.isGroupHeader && !targetHeader.items.length) && visibleFromIdx !== visibleToIdx) { colsToMove = dragHeader.isGroupHeader ? dragHeader.query(':not([hidden]):not([isGroupHeader])').length : 1; if ((visibleFromIdx <= visibleToIdx) && colsToMove > 1) { visibleToIdx -= colsToMove; } toCt.getRootHeaderCt().grid.view.moveColumn(visibleFromIdx, visibleToIdx, colsToMove); } fromCtRoot.fireEvent('columnmove', fromCt, dragHeader, visibleFromIdx, visibleToIdx); fromCt.isDDMoveInGrid = toCt.isDDMoveInGrid = false; if (toCt.isGroupHeader && !fromCt.isGroupHeader) { if (fromCt !== toCt) { dragHeader.savedFlex = dragHeader.flex; delete dragHeader.flex; dragHeader.width = savedWidth; } } else if (!fromCt.isGroupHeader) { if (dragHeader.savedFlex) { dragHeader.flex = dragHeader.savedFlex; delete dragHeader.width; } } Ext.resumeLayouts(true); } } }); Ext.define('Ext.grid.plugin.HeaderReorderer', { extend: 'Ext.plugin.Abstract', requires: [ 'Ext.grid.header.DragZone', 'Ext.grid.header.DropZone' ], alias: 'plugin.gridheaderreorderer', init: function(headerCt) { this.headerCt = headerCt; headerCt.on({ boxready: this.onHeaderCtRender, single: true, scope: this }); }, destroy: function() { Ext.destroy(this.dragZone, this.dropZone); }, onHeaderCtRender: function() { var me = this; me.dragZone = new Ext.grid.header.DragZone(me.headerCt); me.dropZone = new Ext.grid.header.DropZone(me.headerCt); if (me.disabled) { me.dragZone.disable(); } }, enable: function() { this.disabled = false; if (this.dragZone) { this.dragZone.enable(); } }, disable: function() { this.disabled = true; if (this.dragZone) { this.dragZone.disable(); } } }); Ext.define('Ext.grid.header.Container', { extend: 'Ext.container.Container', requires: [ 'Ext.grid.ColumnLayout', 'Ext.grid.plugin.HeaderResizer', 'Ext.grid.plugin.HeaderReorderer', 'Ext.util.KeyNav' ], uses: [ 'Ext.grid.column.Column', 'Ext.grid.ColumnManager', 'Ext.menu.Menu', 'Ext.menu.CheckItem', 'Ext.menu.Separator' ], mixins: [ 'Ext.util.FocusableContainer' ], border: true, alias: 'widget.headercontainer', baseCls: Ext.baseCSSPrefix + 'grid-header-ct', dock: 'top', weight: 100, defaultType: 'gridcolumn', detachOnRemove: false, defaultWidth: 100, sortAscText: 'Sort Ascending', sortDescText: 'Sort Descending', sortClearText: 'Clear Sort', columnsText: 'Columns', headerOpenCls: Ext.baseCSSPrefix + 'column-header-open', menuSortAscCls: Ext.baseCSSPrefix + 'hmenu-sort-asc', menuSortDescCls: Ext.baseCSSPrefix + 'hmenu-sort-desc', menuColsIcon: Ext.baseCSSPrefix + 'cols-icon', ddLock: false, dragging: false, sortOnClick: true, enableFocusableContainer: false, childHideCount: 0, sortable: true, enableColumnHide: true, initComponent: function() { var me = this; me.headerCounter = 0; me.plugins = me.plugins || []; me.defaults = me.defaults || {}; if (!me.isColumn) { if (me.enableColumnResize) { me.resizer = new Ext.grid.plugin.HeaderResizer(); me.plugins.push(me.resizer); } if (me.enableColumnMove) { me.reorderer = new Ext.grid.plugin.HeaderReorderer(); me.plugins.push(me.reorderer); } } if (me.isColumn && !me.isGroupHeader) { if (!me.items || me.items.length === 0) { me.isContainer = me.isFocusableContainer = false; me.focusable = true; me.layout = { type: 'container', calculate: Ext.emptyFn }; } } else { me.layout = Ext.apply({ type: 'gridcolumn', align: 'stretch' }, me.initialConfig.layout); me.defaults.columnLines = me.columnLines; if (!me.isGroupHeader) { me.isRootHeader = true; if (!me.hiddenHeaders) { me.enableFocusableContainer = true; me.ariaRole = 'row'; } me.columnManager = new Ext.grid.ColumnManager(false, me); me.visibleColumnManager = new Ext.grid.ColumnManager(true, me); if (me.grid) { me.grid.columnManager = me.columnManager; me.grid.visibleColumnManager = me.visibleColumnManager; } } else { me.visibleColumnManager = new Ext.grid.ColumnManager(true, me); me.columnManager = new Ext.grid.ColumnManager(false, me); } } me.menuTask = new Ext.util.DelayedTask(me.updateMenuDisabledState, me); me.callParent(); }, insertNestedHeader: function(moveHeader) { var me = this, fromCt = moveHeader.ownerCt, toCt = me.ownerCt, layoutOwner = toCt.layout.owner, toIndex; if (fromCt) { if (me.isGroupHeader && !toCt.isNestedParent) { toIndex = layoutOwner.items.indexOf(me); } fromCt.remove(moveHeader, false); } if (toIndex === undefined) { toIndex = layoutOwner.items.indexOf(me); } layoutOwner.insert(toIndex, moveHeader); }, isNested: function() { return !!this.getRootHeaderCt().down('[isNestedParent]'); }, isNestedGroupHeader: function() { var header = this, items = header.getRefOwner().query('>:not([hidden])'); return (items.length === 1 && items[0] === header); }, maybeShowNestedGroupHeader: function() { var items = this.items, item; if (items && items.length === 1 && (item = items.getAt(0)) && item.hidden) { item.show(); } }, setNestedParent: function(target) { target.isNestedParent = false; target.ownerCt.isNestedParent = !!(this.ownerCt.items.length === 1 && target.ownerCt.items.length === 1); }, initEvents: function() { var me = this, onHeaderCtEvent, listeners; me.callParent(); if (!me.isColumn && !me.isGroupHeader) { onHeaderCtEvent = me.onHeaderCtEvent; listeners = { click: onHeaderCtEvent, dblclick: onHeaderCtEvent, contextmenu: onHeaderCtEvent, mouseover: me.onHeaderCtMouseOver, mouseout: me.onHeaderCtMouseOut, scope: me }; if (Ext.supports.Touch) { listeners.longpress = me.onHeaderCtLongPress; } me.mon(me.el, listeners); } }, onHeaderCtEvent: function(e, t) { var me = this, headerEl = me.getHeaderElByEvent(e), header, targetEl, activeHeader; if (me.longPressFired) { me.longPressFired = false; return; } if (headerEl && !me.ddLock) { header = Ext.getCmp(headerEl.id); if (header) { targetEl = header[header.clickTargetName]; if ((!header.isGroupHeader && !header.isContainer) || e.within(targetEl)) { if (e.type === 'click' || e.type === 'tap') { activeHeader = header.onTitleElClick(e, targetEl, me.sortOnClick); if (activeHeader) { me.onHeaderTriggerClick(activeHeader, e, Ext.supports.Touch ? activeHeader.el : activeHeader.triggerEl); } else { me.onHeaderClick(header, e, t); } } else if (e.type === 'contextmenu') { me.onHeaderContextMenu(header, e, t); } else if (e.type === 'dblclick' && header.resizable) { header.onTitleElDblClick(e, targetEl.dom); } } } } }, onHeaderCtMouseOver: function(e, t) { var headerEl, header, targetEl; if (!e.within(this.el, true)) { headerEl = e.getTarget('.' + Ext.grid.column.Column.prototype.baseCls); header = headerEl && Ext.getCmp(headerEl.id); if (header) { targetEl = header[header.clickTargetName]; if (e.within(targetEl)) { header.onTitleMouseOver(e, targetEl.dom); } } } }, onHeaderCtMouseOut: function(e, t) { var headerSelector = '.' + Ext.grid.column.Column.prototype.baseCls, outHeaderEl = e.getTarget(headerSelector), inHeaderEl = e.getRelatedTarget(headerSelector), header, targetEl; if (outHeaderEl !== inHeaderEl) { if (outHeaderEl) { header = Ext.getCmp(outHeaderEl.id); if (header) { targetEl = header[header.clickTargetName]; header.onTitleMouseOut(e, targetEl.dom); } } if (inHeaderEl) { header = Ext.getCmp(inHeaderEl.id); if (header) { targetEl = header[header.clickTargetName]; header.onTitleMouseOver(e, targetEl.dom); } } } }, onHeaderCtLongPress: function(e) { var me = this, headerEl = me.getHeaderElByEvent(e), header = Ext.getCmp(headerEl.id); if (!header.menuDisabled) { me.longPressFired = true; me.showMenuBy(e, headerEl, header); } }, getHeaderElByEvent: function(e) { return e.getTarget('.' + Ext.grid.column.Column.prototype.baseCls); }, isLayoutRoot: function() { if (this.hiddenHeaders) { return false; } return this.callParent(); }, getRootHeaderCt: function() { var me = this; return me.isRootHeader ? me : me.up('[isRootHeader]'); }, onDestroy: function() { var me = this; if (me.menu) { me.menu.un('hide', me.onMenuHide, me); } me.menuTask.cancel(); me.callParent(); Ext.destroy(me.visibleColumnManager, me.columnManager, me.menu); me.columnManager = me.visibleColumnManager = null; }, applyColumnsState: function(columns) { if (!columns || !columns.length) { return; } var me = this, items = me.items.items, count = items.length, i = 0, length = columns.length, c, col, columnState, index, moved = false, newOrder = [], stateHash = {}, newCols = []; for (c = 0; c < length; c++) { columnState = columns[c]; columnState.index = c; stateHash[columnState.id] = columnState; } for (i = 0; i < count; i++) { col = items[i]; columnState = stateHash[col.getStateId()]; if (columnState) { index = columnState.index; newOrder[index] = col; if (i !== index) { moved = true; } if (col.applyColumnState) { col.applyColumnState(columnState); } } else { newCols.push({ index: i, column: col }); } } newOrder = Ext.Array.clean(newOrder); length = newCols.length; if (length) { for (i = 0; i < length; i++) { columnState = newCols[i]; index = columnState.index; if (index < newOrder.length) { moved = true; Ext.Array.splice(newOrder, index, 0, columnState.column); } else { newOrder.push(columnState.column); } } } if (moved) { me.removeAll(false); me.add(newOrder); me.purgeCache(); } }, getColumnsState: function() { var me = this, columns = [], state; me.items.each(function(col) { state = col.getColumnState && col.getColumnState(); if (state) { columns.push(state); } }); return columns; }, onAdd: function(c) { var me = this; if (!c.headerId) { c.headerId = c.initialConfig.id || Ext.id(null, 'header-'); } if (c.sortable === undefined) { c.sortable = me.sortable; } if (!c.getStateId()) { c.stateId = c.initialConfig.id || ('h' + (++me.headerCounter)); } if (!me._usedIDs) { me._usedIDs = {}; } if (me._usedIDs[c.headerId]) { Ext.log.warn(this.$className + ' attempted to reuse an existing id: ' + c.headerId); } me._usedIDs[c.headerId] = true; me.callParent(arguments); me.onHeadersChanged(c, me.isDDMoveInGrid); }, move: function(fromIdx, toIdx) { var me = this, items = me.items, headerToMove; if (fromIdx.isComponent) { headerToMove = fromIdx; fromIdx = items.indexOf(headerToMove); } else { headerToMove = items.getAt(fromIdx); } headerToMove.visibleFromIdx = me.getRootHeaderCt().visibleColumnManager.indexOf(headerToMove); me.callParent(arguments); }, onMove: function(headerToMove, fromIdx, toIdx) { var me = this, gridHeaderCt = me.getRootHeaderCt(), gridVisibleColumnManager = gridHeaderCt.visibleColumnManager, numColsToMove = 1, visibleToIdx; me.onHeadersChanged(headerToMove, true); visibleToIdx = gridVisibleColumnManager.indexOf(headerToMove); if (visibleToIdx >= headerToMove.visibleFromIdx) { visibleToIdx++; } me.callParent(arguments); if (headerToMove.isGroupHeader) { numColsToMove = headerToMove.visibleColumnManager.getColumns().length; } gridHeaderCt.onHeaderMoved(headerToMove, numColsToMove, headerToMove.visibleFromIdx, visibleToIdx); }, onRemove: function(c) { var me = this, ownerCt = me.ownerCt; me.callParent(arguments); if (!me._usedIDs) { me._usedIDs = {}; } delete me._usedIDs[c.headerId]; if (!me.destroying) { if (!me.isDDMoveInGrid) { me.onHeadersChanged(c, false); } if (me.isGroupHeader && !me.isNestedParent && ownerCt && !me.items.getCount()) { if (c.rendered) { me.detachComponent(c); } Ext.suspendLayouts(); ownerCt.remove(me); Ext.resumeLayouts(true); } } }, onHeadersChanged: function(c, isMove) { var gridPanel, gridHeaderCt = this.getRootHeaderCt(); this.purgeHeaderCtCache(this); if (gridHeaderCt) { gridHeaderCt.onColumnsChanged(); if (!c.isGroupHeader) { gridPanel = gridHeaderCt.ownerCt; if (gridPanel && !isMove) { gridPanel.onHeadersChanged(gridHeaderCt, c); } } } }, onHeaderMoved: function(header, colsToMove, fromIdx, toIdx) { var me = this, gridSection = me.ownerCt; if (me.rendered) { if (gridSection && gridSection.onHeaderMove) { gridSection.onHeaderMove(me, header, colsToMove, fromIdx, toIdx); } me.fireEvent('columnmove', me, header, fromIdx, toIdx); } }, onColumnsChanged: function() { var me = this, menu = me.menu, columnItemSeparator, columnItem; if (me.rendered) { me.fireEvent('columnschanged', me); if (menu && (columnItemSeparator = menu.child('#columnItemSeparator'))) { columnItem = menu.child('#columnItem'); columnItemSeparator.destroy(); columnItem.destroy(); } } }, lookupComponent: function(comp) { var result = this.callParent(arguments); if (!result.isGroupHeader && result.width === undefined && !result.flex) { result.width = this.defaultWidth; } return result; }, setSortState: function() { var store = this.up('[store]').store, columns = this.visibleColumnManager.getColumns(), len = columns.length, i, header, sorter; for (i = 0; i < len; i++) { header = columns[i]; sorter = store.getSorters().get(header.getSortParam()); header.setSortState(sorter); } }, getHeaderMenu: function() { var menu = this.getMenu(), item; if (menu) { item = menu.child('#columnItem'); if (item) { return item.menu; } } return null; }, onHeaderVisibilityChange: function(header, visible) { var me = this, menu = me.getHeaderMenu(), item; me.purgeHeaderCtCache(header.ownerCt); if (menu) { item = me.getMenuItemForHeader(menu, header); if (item) { item.setChecked(visible, true); } if (menu.isVisible()) { me.menuTask.delay(50); } } }, updateMenuDisabledState: function(menu) { var me = this, columns = me.query(':not([hidden])'), i, len = columns.length, item, checkItem, method; if (!menu) { menu = me.getMenu(); } for (i = 0; i < len; ++i) { item = columns[i]; checkItem = me.getMenuItemForHeader(menu, item); if (checkItem) { method = item.isHideable() ? 'enable' : 'disable'; if (checkItem.menu) { method += 'CheckChange'; } checkItem[method](); } } }, getMenuItemForHeader: function(menu, header) { return header ? menu.down('menucheckitem[headerId=' + header.id + ']') : null; }, onHeaderShow: function(header) { var me = this, ownerCt = me.ownerCt; if (!ownerCt) { return; } if (me.forceFit) { delete me.flex; } me.onHeaderVisibilityChange(header, true); ownerCt.onHeaderShow(me, header); me.fireEvent('columnshow', me, header); me.fireEvent('columnschanged', this); }, onHeaderHide: function(header) { var me = this, ownerCt = me.ownerCt; if (!ownerCt) { return; } me.onHeaderVisibilityChange(header, false); ownerCt.onHeaderHide(me, header); me.fireEvent('columnhide', me, header); me.fireEvent('columnschanged', this); }, onHeaderResize: function(header, w) { var me = this, gridSection = me.ownerCt; if (gridSection) { gridSection.onHeaderResize(me, header, w); } me.fireEvent('columnresize', me, header, w); }, onHeaderClick: function(header, e, t) { var me = this, selModel = header.getView().getSelectionModel(); header.fireEvent('headerclick', me, header, e, t); if (me.fireEvent('headerclick', me, header, e, t) !== false) { if (selModel.onHeaderClick) { selModel.onHeaderClick(me, header, e); } } }, onHeaderContextMenu: function(header, e, t) { header.fireEvent('headercontextmenu', this, header, e, t); this.fireEvent('headercontextmenu', this, header, e, t); }, onHeaderTriggerClick: function(header, e, t) { var me = this; if (header.fireEvent('headertriggerclick', me, header, e, t) !== false && me.fireEvent('headertriggerclick', me, header, e, t) !== false) { if (header.activeMenu) { if (e.pointerType) { header.activeMenu.hide(); } else { header.activeMenu.focus(); } } else { me.showMenuBy(e, t, header); } } }, showMenuBy: function(clickEvent, t, header) { var menu = this.getMenu(), ascItem = menu.down('#ascItem'), descItem = menu.down('#descItem'), sortableMth; menu.activeHeader = menu.ownerCmp = header; header.setMenuActive(menu); sortableMth = header.sortable ? 'enable' : 'disable'; if (ascItem) { ascItem[sortableMth](); } if (descItem) { descItem[sortableMth](); } menu.autoFocus = !clickEvent || !clickEvent.pointerType; menu.showBy(t, 'tl-bl?'); if (!menu.isVisible()) { this.onMenuHide(menu); } }, hideMenu: function() { if (this.menu) { this.menu.hide(); } }, onMenuHide: function(menu) { menu.activeHeader.setMenuActive(false); }, purgeHeaderCtCache: function(headerCt) { while (headerCt) { headerCt.purgeCache(); if (headerCt.isRootHeader) { return; } headerCt = headerCt.ownerCt; } }, purgeCache: function() { var me = this, visibleColumnManager = me.visibleColumnManager, columnManager = me.columnManager; me.gridVisibleColumns = me.gridDataColumns = me.hideableColumns = null; if (visibleColumnManager) { visibleColumnManager.invalidate(); columnManager.invalidate(); } }, getMenu: function() { var me = this; if (!me.menu) { me.menu = new Ext.menu.Menu({ hideOnParentHide: false, items: me.getMenuItems(), listeners: { beforeshow: me.beforeMenuShow, hide: me.onMenuHide, scope: me } }); me.fireEvent('menucreate', me, me.menu); } return me.menu; }, beforeMenuShow: function(menu) { var me = this, columnItem = menu.child('#columnItem'), hideableColumns, insertPoint; if (!columnItem) { hideableColumns = me.enableColumnHide ? me.getColumnMenu(me) : null; insertPoint = me.sortable ? 2 : 0; if (hideableColumns && hideableColumns.length) { menu.insert(insertPoint, [ { itemId: 'columnItemSeparator', xtype: 'menuseparator' }, { itemId: 'columnItem', text: me.columnsText, iconCls: me.menuColsIcon, menu: { items: hideableColumns }, hideOnClick: false } ]); } } me.updateMenuDisabledState(me.menu); }, getMenuItems: function() { var me = this, menuItems = [], hideableColumns = me.enableColumnHide ? me.getColumnMenu(me) : null; if (me.sortable) { menuItems = [ { itemId: 'ascItem', text: me.sortAscText, iconCls: me.menuSortAscCls, handler: me.onSortAscClick, scope: me }, { itemId: 'descItem', text: me.sortDescText, iconCls: me.menuSortDescCls, handler: me.onSortDescClick, scope: me } ]; } if (hideableColumns && hideableColumns.length) { if (me.sortable) { menuItems.push({ itemId: 'columnItemSeparator', xtype: 'menuseparator' }); } menuItems.push({ itemId: 'columnItem', text: me.columnsText, iconCls: me.menuColsIcon, menu: hideableColumns, hideOnClick: false }); } return menuItems; }, onSortAscClick: function() { var menu = this.getMenu(), activeHeader = menu.activeHeader; activeHeader.sort('ASC'); }, onSortDescClick: function() { var menu = this.getMenu(), activeHeader = menu.activeHeader; activeHeader.sort('DESC'); }, 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 = new Ext.menu.CheckItem({ text: item.menuText || item.text, checked: !item.hidden, hideOnClick: false, headerId: item.id, menu: item.isGroupHeader ? this.getColumnMenu(item) : undefined, checkHandler: this.onColumnCheckChange, scope: this }); menuItems.push(menuItem); } return menuItems.length ? menuItems : null; }, onColumnCheckChange: function(checkItem, checked) { var header = Ext.getCmp(checkItem.headerId), headerId; if (header.rendered) { header[checked ? 'show' : 'hide'](); headerId = header.lastCheckedHeaderId; if (checked && headerId) { header.getRootHeaderCt().getMenu().down('[headerId=' + headerId + ']').setChecked(true); header.lastCheckedHeaderId = null; } } else { header.hidden = !checked; } }, getColumnCount: function() { return this.getGridColumns().length; }, getTableWidth: function() { var fullWidth = 0, headers = this.getVisibleGridColumns(), headersLn = headers.length, i; for (i = 0; i < headersLn; i++) { fullWidth += headers[i].getCellWidth() || 0; } return fullWidth; }, getVisibleGridColumns: function() { var me = this, allColumns, rootHeader, result, len, i, column; if (me.gridVisibleColumns) { return me.gridVisibleColumns; } allColumns = me.getGridColumns(); rootHeader = me.getRootHeaderCt(); result = []; len = allColumns.length; for (i = 0; i < len; i++) { column = allColumns[i]; if (!column.hidden && !column.isColumnHidden(rootHeader)) { result[result.length] = column; } } me.gridVisibleColumns = result; return result; }, isColumnHidden: function(rootHeader) { var owner = this.getRefOwner(); while (owner && owner !== rootHeader) { if (owner.hidden) { return true; } owner = owner.getRefOwner(); } return false; }, getGridColumns: function( inResult, hiddenAncestor) { if (!inResult && this.gridDataColumns) { return this.gridDataColumns; } var me = this, result = inResult || [], items, i, len, item, lastVisibleColumn; hiddenAncestor = hiddenAncestor || me.hidden; if (me.items) { items = me.items.items; if (items) { for (i = 0 , len = items.length; i < len; i++) { item = items[i]; if (item.isGroupHeader) { item.visibleIndex = result.length; item.getGridColumns(result, hiddenAncestor); } else { item.hiddenAncestor = hiddenAncestor; result.push(item); } } } } if (!inResult) { me.gridDataColumns = result; } if (!inResult && len) { for (i = 0 , len = result.length; i < len; i++) { item = result[i]; item.fullColumnIndex = i; item.isFirstVisible = item.isLastVisible = false; if (!(item.hidden || item.hiddenAncestor)) { if (!lastVisibleColumn) { item.isFirstVisible = true; } lastVisibleColumn = item; } } if (lastVisibleColumn) { lastVisibleColumn.isLastVisible = true; } } return result; }, getHideableColumns: function() { var me = this, result = me.hideableColumns; if (!result) { result = me.hideableColumns = me.query('[hideable]'); } return result; }, getHeaderIndex: function(header) { if (!this.columnManager) { this.columnManager = this.getRootHeaderCt().columnManager; } return this.columnManager.getHeaderIndex(header); }, getHeaderAtIndex: function(index) { if (!this.columnManager) { this.columnManager = this.getRootHeaderCt().columnManager; } return this.columnManager.getHeaderAtIndex(index); }, getVisibleHeaderClosestToIndex: function(index) { if (!this.visibleColumnManager) { this.visibleColumnManager = this.getRootHeaderCt().visibleColumnManager; } return this.visibleColumnManager.getVisibleHeaderClosestToIndex(index); }, applyForceFit: function(header) { var me = this, view = me.view, minWidth = Ext.grid.plugin.HeaderResizer.prototype.minColWidth, useMinWidthForFlex = false, defaultWidth = Ext.grid.header.Container.prototype.defaultWidth, availFlex = me.el.dom.clientWidth - (view.el.dom.scrollHeight > view.el.dom.clientHeight ? Ext.getScrollbarSize().width : 0), totalFlex = 0, items = me.getVisibleGridColumns(), hidden = header.hidden, len, i, item, maxAvailFlexOneColumn, myWidth; function getTotalFlex() { for (i = 0 , len = items.length; i < len; i++) { item = items[i]; if (item === header) { continue; } item.flex = item.flex || item.width || item.getWidth(); totalFlex += item.flex; item.width = null; } } function applyWidth() { var isCurrentHeader; for (i = 0 , len = items.length; i < len; i++) { item = items[i]; isCurrentHeader = (item === header); if (useMinWidthForFlex && !isCurrentHeader) { item.flex = minWidth; item.width = null; } else if (!isCurrentHeader) { myWidth = item.flex || defaultWidth; item.flex = Math.max(Math.ceil((myWidth / totalFlex) * availFlex), minWidth); item.width = null; } item.setWidth(item.width || item.flex); } } Ext.suspendLayouts(); maxAvailFlexOneColumn = (availFlex - ((items.length + 1) * minWidth)); header.flex = null; if (hidden) { myWidth = header.width || header.savedWidth; header.savedWidth = null; } else { myWidth = view.getMaxContentWidth(header); } if (myWidth > maxAvailFlexOneColumn) { header.width = maxAvailFlexOneColumn; useMinWidthForFlex = true; } else { header.width = myWidth; availFlex -= myWidth + defaultWidth; getTotalFlex(); } applyWidth(); Ext.resumeLayouts(true); }, autoSizeColumn: function(header) { var view = this.view; if (view) { view.autoSizeColumn(header); if (this.forceFit) { this.applyForceFit(header); } } }, privates: { beginChildHide: function() { ++this.childHideCount; }, endChildHide: function() { --this.childHideCount; }, getFocusables: function() { return this.isRootHeader ? this.getVisibleGridColumns() : this.items.items; }, createFocusableContainerKeyNav: function(el) { var me = this; return new Ext.util.KeyNav(el, { scope: me, down: me.showHeaderMenu, left: me.onFocusableContainerLeftKey, right: me.onFocusableContainerRightKey, space: me.onHeaderActivate, enter: me.onHeaderActivate }); }, showHeaderMenu: function(e) { var column = this.getFocusableFromEvent(e); if (column && column.isColumn && column.triggerEl) { this.onHeaderTriggerClick(column, e, column.triggerEl); } }, onHeaderActivate: function(e) { var column = this.getFocusableFromEvent(e), view, lastFocused; if (column && column.isColumn) { view = column.getView(); if (column.sortable && this.sortOnClick) { lastFocused = view.getNavigationModel().getLastFocused(); column.toggleSortState(); if (lastFocused) { view.ownerCt.ensureVisible(lastFocused.record); } } this.onHeaderClick(column, e, column.el); } }, onFocusableContainerMousedown: function(e, target) { var targetCmp = Ext.Component.fromElement(target); if (targetCmp === this) { e.preventDefault(); } else { targetCmp.focus(); } } } }); Ext.define('Ext.grid.ColumnComponentLayout', { extend: 'Ext.layout.component.Auto', alias: 'layout.columncomponent', type: 'columncomponent', setWidthInDom: true, _paddingReset: { paddingTop: '', paddingBottom: '' }, columnAutoCls: Ext.baseCSSPrefix + 'column-header-text-container-auto', beginLayout: function(ownerContext) { this.callParent(arguments); ownerContext.titleContext = ownerContext.getEl('titleEl'); }, beginLayoutCycle: function(ownerContext) { var me = this, owner = me.owner, shrinkWrap = ownerContext.widthModel.shrinkWrap; me.callParent(arguments); if (shrinkWrap) { owner.el.setWidth(''); } owner.textContainerEl[shrinkWrap ? 'addCls' : 'removeCls'](me.columnAutoCls); owner.titleEl.setStyle(me._paddingReset); }, publishInnerHeight: function(ownerContext, outerHeight) { var me = this, owner = me.owner, innerHeight; if (owner.getRootHeaderCt().hiddenHeaders) { ownerContext.setProp('innerHeight', 0); return; } if (!ownerContext.hasRawContent) { if (owner.headerWrap && !ownerContext.hasDomProp('width')) { me.done = false; return; } innerHeight = outerHeight - ownerContext.getBorderInfo().height; ownerContext.setProp('innerHeight', innerHeight - owner.titleEl.getHeight(), false); } }, measureContentHeight: function(ownerContext) { return ownerContext.el.dom.offsetHeight; }, publishInnerWidth: function(ownerContext, outerWidth) { if (!ownerContext.hasRawContent) { ownerContext.setProp('innerWidth', outerWidth - ownerContext.getBorderInfo().width, false); } }, calculateOwnerHeightFromContentHeight: function(ownerContext, contentHeight) { var result = this.callParent(arguments), owner = this.owner; if (!ownerContext.hasRawContent) { if (!owner.headerWrap || ownerContext.hasDomProp('width')) { return contentHeight + owner.titleEl.getHeight() + ownerContext.getBorderInfo().height; } return null; } return result; }, calculateOwnerWidthFromContentWidth: function(ownerContext, contentWidth) { var owner = this.owner, padWidth = ownerContext.getPaddingInfo().width, triggerOffset = this.getTriggerOffset(owner, ownerContext), inner; if (owner.isGroupHeader) { inner = contentWidth; } else { inner = Math.max(contentWidth, owner.textEl.getWidth() + ownerContext.titleContext.getPaddingInfo().width); } return inner + padWidth + triggerOffset; }, getTriggerOffset: function(owner, ownerContext) { var width = 0; if (ownerContext.widthModel.shrinkWrap && !owner.menuDisabled) { if (owner.query('>:not([hidden])').length === 0) { width = owner.getTriggerElWidth(); } } return width; } }); Ext.define('Ext.grid.column.Column', { extend: 'Ext.grid.header.Container', xtype: 'gridcolumn', requires: [ 'Ext.grid.ColumnComponentLayout', 'Ext.grid.ColumnLayout', 'Ext.app.bind.Template' ], alternateClassName: 'Ext.grid.Column', config: { triggerVisible: false }, baseCls: Ext.baseCSSPrefix + 'column-header', hoverCls: Ext.baseCSSPrefix + 'column-header-over', handleWidth: Ext.supports.Touch ? 10 : 4, ariaRole: 'columnheader', enableFocusableContainer: false, sortState: null, possibleSortStates: [ 'ASC', 'DESC' ], childEls: [ 'titleEl', 'triggerEl', 'textEl', 'textContainerEl' ], headerWrap: false, renderTpl: [ '
', Ext.baseCSSPrefix, 'leaf-column-header', ' ', Ext.baseCSSPrefix, 'column-header-inner-empty">', '', '', '', '{text}', '', '', '', '', '', '', '
', '{%this.renderContainer(out,values)%}' ], dataIndex: null, text: ' ', menuText: null, emptyCellText: ' ', sortable: true, resizable: true, hideable: true, menuDisabled: false, renderer: false, align: 'left', draggable: true, tooltipType: 'qtip', initDraggable: Ext.emptyFn, tdCls: '', producesHTML: true, isHeader: true, isColumn: true, tabIndex: -1, ascSortCls: Ext.baseCSSPrefix + 'column-header-sort-ASC', descSortCls: Ext.baseCSSPrefix + 'column-header-sort-DESC', componentLayout: 'columncomponent', groupSubHeaderCls: Ext.baseCSSPrefix + 'group-sub-header', groupHeaderCls: Ext.baseCSSPrefix + 'group-header', clickTargetName: 'titleEl', detachOnRemove: true, initResizable: Ext.emptyFn, rendererNames: { column: 'renderer', edit: 'editRenderer', summary: 'summaryRenderer' }, formatterNames: { column: 'formatter', edit: 'editFormatter', summary: 'summaryFormatter' }, initComponent: function() { var me = this; me.rendererScope = me.initialConfig.scope; if (me.header != null) { me.text = me.header; me.header = null; } if (me.cellWrap) { me.tdCls = (me.tdCls || '') + ' ' + Ext.baseCSSPrefix + 'wrap-cell'; } if (me.columns != null) { 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.'); } me.items = me.columns; me.columns = me.flex = me.width = null; me.cls = (me.cls || '') + ' ' + me.groupHeaderCls; me.sortable = me.resizable = false; me.align = 'center'; } else { if (me.flex) { me.minWidth = me.minWidth || Ext.grid.plugin.HeaderResizer.prototype.minColWidth; } } me.addCls(Ext.baseCSSPrefix + 'column-header-align-' + me.align); me.setupRenderer(); me.setupRenderer('edit'); me.setupRenderer('summary'); me.callParent(arguments); }, bindFormatter: function(format) { var me = this; return function(v) { return format.format(v, format.scope || me.rendererScope || me.resolveListenerScope()); }; }, bindRenderer: function(renderer) { var me = this; if (renderer in Ext.util.Format) { Ext.log.warn('Use "formatter" config instead of "renderer" to use ' + 'Ext.util.Format to format cell values'); } me.hasCustomRenderer = true; return function() { return Ext.callback(renderer, me.rendererScope, arguments, 0, me); }; }, setupRenderer: function(type) { type = type || 'column'; var me = this, format = me[me.formatterNames[type]], renderer = me[me.rendererNames[type]], isColumnRenderer = type === 'column', scoped; if (!format) { if (renderer) { if (typeof renderer === 'string') { renderer = me[me.rendererNames[type]] = me.bindRenderer(renderer); } if (isColumnRenderer) { me.hasCustomRenderer = renderer.length > 1; } } else if (isColumnRenderer && me.defaultRenderer) { me.renderer = me.defaultRenderer; me.usingDefaultRenderer = true; } } else { scoped = format.indexOf('this.') === 0; if (scoped) { format = format.substring(5); } format = Ext.app.bind.Template.prototype.parseFormat(format); me[me.formatterNames[type]] = null; if (scoped) { format.scope = null; } else if (!Ext.util.Format[format.fmt]) { Ext.Error.raise('Invalid formatter specified: "' + format.fmt + '"'); } me[me.rendererNames[type]] = me.bindFormatter(format); } }, getView: function() { var rootHeaderCt = this.getRootHeaderCt(); if (rootHeaderCt) { return rootHeaderCt.view; } }, onResize: function(width, height, oldWidth, oldHeight) { var me = this, view, bufferedRenderer; me.callParent(arguments); if (oldWidth && me.cellWrap) { view = me.getView(); if (view) { bufferedRenderer = view.bufferedRenderer; if (bufferedRenderer) { bufferedRenderer.onWrappedColumnWidthChange(oldWidth, width); } } } }, onFocusLeave: function(e) { this.callParent([ e ]); if (this.activeMenu) { this.activeMenu.hide(); } }, initItems: function() { var me = this; me.callParent(arguments); if (me.isGroupHeader) { if (me.config.hidden || !me.hasVisibleChildColumns()) { me.hide(); } } }, hasVisibleChildColumns: function() { var items = this.items.items, len = items.length, i, item; for (i = 0; i < len; ++i) { item = items[i]; if (item.isColumn && !item.hidden) { return true; } } return false; }, onAdd: function(child) { var me = this; if (child.isColumn) { child.isSubHeader = true; child.addCls(me.groupSubHeaderCls); } if (me.isGroupHeader && me.hidden && me.hasVisibleChildColumns()) { me.show(); } me.callParent([ child ]); }, onRemove: function(child) { var me = this; if (child.isSubHeader) { child.isSubHeader = false; child.removeCls(me.groupSubHeaderCls); } me.callParent([ child ]); if (!(me.isDestroyed || me.destroying) && !me.hasVisibleChildColumns() && !me.ownerCt.isNested()) { me.hide(); } }, initRenderData: function() { var me = this, tipMarkup = '', tip = me.tooltip, text = me.text, attr = me.tooltipType === 'qtip' ? 'data-qtip' : 'title'; if (!Ext.isEmpty(tip)) { tipMarkup = attr + '="' + tip + '" '; } return Ext.applyIf(me.callParent(arguments), { text: text, empty: text === ' ' || text === ' ' || text === '', menuDisabled: me.menuDisabled, tipMarkup: tipMarkup, triggerStyle: this.getTriggerVisible() ? 'display:block' : '' }); }, applyColumnState: function(state) { var me = this; me.applyColumnsState(state.columns); if (state.hidden != null) { me.hidden = state.hidden; } if (state.locked != null) { me.locked = state.locked; } if (state.sortable != null) { me.sortable = state.sortable; } if (state.width != null) { me.flex = null; me.width = state.width; } else if (state.flex != null) { me.width = null; me.flex = state.flex; } }, getColumnState: function() { var me = this, items = me.items.items, iLen = items ? items.length : 0, i, columns = [], state = { id: me.stateId || me.getStateId() }; me.savePropsToState([ 'hidden', 'sortable', 'locked', 'flex', 'width' ], state); if (me.isGroupHeader) { for (i = 0; i < iLen; i++) { columns.push(items[i].getColumnState()); } if (columns.length) { state.columns = columns; } } if ('width' in state) { delete state.flex; } return state; }, getStateId: function() { return (this.stateId = this.stateId || this.headerId); }, setText: function(text) { this.text = text; if (this.rendered) { this.textEl.setHtml(text); } }, getIndex: function() { return this.isGroupColumn ? false : this.getRootHeaderCt().getHeaderIndex(this); }, getVisibleIndex: function() { return this.visibleIndex != null ? this.visibleIndex : this.isGroupColumn ? false : Ext.Array.indexOf(this.getRootHeaderCt().getVisibleGridColumns(), this); }, beforeRender: function() { var me = this, rootHeaderCt = me.getRootHeaderCt(); me.callParent(); if (!me.isSortable() && !me.groupable && !me.lockable && (rootHeaderCt.grid.enableColumnHide === false || !rootHeaderCt.getHideableColumns().length)) { me.menuDisabled = true; } if (me.cellWrap) { me.variableRowHeight = true; } me.protoEl.unselectable(); }, getTriggerElWidth: function() { var me = this, triggerEl = me.triggerEl, width = me.self.triggerElWidth; if (triggerEl && width === undefined) { triggerEl.setStyle('display', 'block'); width = me.self.triggerElWidth = triggerEl.getWidth(); triggerEl.setStyle('display', ''); } return width; }, afterComponentLayout: function(width, height, oldWidth, oldHeight) { var me = this, rootHeaderCt = me.getRootHeaderCt(); me.callParent(arguments); if (rootHeaderCt && (oldWidth != null || me.flex) && width !== oldWidth) { rootHeaderCt.onHeaderResize(me, width); } }, onDestroy: function() { var me = this; Ext.destroy(me.field); me.field = null; me.callParent(arguments); }, onTitleMouseOver: function() { this.titleEl.addCls(this.hoverCls); }, onTitleMouseOut: function() { this.titleEl.removeCls(this.hoverCls); }, onDownKey: function(e) { if (this.triggerEl) { this.onTitleElClick(e, this.triggerEl.dom || this.el.dom); } }, onEnterKey: function(e) { this.onTitleElClick(e, this.el.dom); }, onTitleElDblClick: function(e) { var me = this, prev, leafColumns, headerCt; if (me.isAtStartEdge(e)) { prev = me.previousNode('gridcolumn:not([hidden]):not([isGroupHeader])'); if (prev && prev.getRootHeaderCt() === me.getRootHeaderCt()) { prev.autoSize(); } } else if (me.isAtEndEdge(e)) { if (me.isGroupHeader && e.getPoint().isContainedBy(me.layout.innerCt)) { leafColumns = me.query('gridcolumn:not([hidden]):not([isGroupHeader])'); me.getRootHeaderCt().autoSizeColumn(leafColumns[leafColumns.length - 1]); return; } else { headerCt = me.getRootHeaderCt(); if (headerCt.visibleColumnManager.getColumns().length === 1 && headerCt.forceFit) { return; } } me.autoSize(); } }, autoSize: function() { var me = this, leafColumns, numLeaves, i, headerCt; if (me.isGroupHeader) { leafColumns = me.query('gridcolumn:not([hidden]):not([isGroupHeader])'); numLeaves = leafColumns.length; headerCt = me.getRootHeaderCt(); Ext.suspendLayouts(); for (i = 0; i < numLeaves; i++) { headerCt.autoSizeColumn(leafColumns[i]); } Ext.resumeLayouts(true); return; } me.getRootHeaderCt().autoSizeColumn(me); }, onTitleElClick: function(e, t, sortOnClick) { var me = this, activeHeader, prevSibling; if (Ext.supports.Touch) { prevSibling = me.previousSibling(':not([hidden])'); if (!me.menuDisabled && me.isAtEndEdge(e, parseInt(me.triggerEl.getStyle('width'), 10))) { if (!me.menuDisabled) { activeHeader = me; } } else if (prevSibling && !prevSibling.menuDisabled && me.isAtStartEdge(e)) { activeHeader = prevSibling; } } else { activeHeader = me.triggerEl && (e.target === me.triggerEl.dom || t === me.triggerEl || e.within(me.triggerEl)) ? me : null; } if (sortOnClick !== false && (!activeHeader && !me.isAtStartEdge(e) && !me.isAtEndEdge(e) || e.getKey())) { me.toggleSortState(); } return activeHeader; }, processEvent: function(type, view, cell, recordIndex, cellIndex, e) { return this.fireEvent.apply(this, arguments); }, isSortable: function() { var rootHeader = this.getRootHeaderCt(), grid = rootHeader ? rootHeader.grid : null, sortable = this.sortable; if (grid && grid.sortableColumns === false) { sortable = false; } return sortable; }, toggleSortState: function() { if (this.isSortable()) { this.sort(); } }, sort: function(direction) { var me = this, grid = me.up('tablepanel'), store = grid.store; Ext.suspendLayouts(); me.sorting = true; store.sort(me.getSortParam(), direction, grid.multiColumnSort ? 'multi' : 'replace'); delete me.sorting; Ext.resumeLayouts(true); }, getSortParam: function() { return this.dataIndex; }, setSortState: function(sorter) { var me = this, direction = sorter && sorter.getDirection(), ascCls = me.ascSortCls, descCls = me.descSortCls, rootHeaderCt = me.getRootHeaderCt(), changed; switch (direction) { case 'DESC': if (!me.hasCls(descCls)) { me.addCls(descCls); me.sortState = 'DESC'; changed = true; }; me.removeCls(ascCls); break; case 'ASC': if (!me.hasCls(ascCls)) { me.addCls(ascCls); me.sortState = 'ASC'; changed = true; }; me.removeCls(descCls); break; default: me.removeCls([ ascCls, descCls ]); me.sortState = null; break; } if (changed) { rootHeaderCt.fireEvent('sortchange', rootHeaderCt, me, direction); } }, isHideable: function() { var result = { hideCandidate: this, result: this.hideable }; if (result.result) { this.ownerCt.bubble(this.hasOtherMenuEnabledChildren, null, [ result ]); } return result.result; }, hasOtherMenuEnabledChildren: function(result) { var visibleChildren, count; if (!this.isXType('headercontainer')) { result.result = false; return false; } visibleChildren = this.query('>:not([hidden]):not([menuDisabled])'); count = visibleChildren.length; if (Ext.Array.contains(visibleChildren, result.hideCandidate)) { count--; } if (count) { return false; } result.hideCandidate = this; }, isLockable: function() { var result = { result: this.lockable !== false }; if (result.result) { this.ownerCt.bubble(this.hasMultipleVisibleChildren, null, [ result ]); } return result.result; }, isLocked: function() { return this.locked || !!this.up('[isColumn][locked]', '[isRootHeader]'); }, hasMultipleVisibleChildren: function(result) { if (!this.isXType('headercontainer')) { result.result = false; return false; } if (this.query('>:not([hidden])').length > 1) { return false; } }, hide: function() { var me = this, rootHeaderCt = me.getRootHeaderCt(), owner = me.getRefOwner(); if (owner.constructing) { me.callParent(); return me; } if (me.rendered && !me.isVisible()) { return me; } if (rootHeaderCt.forceFit) { me.visibleSiblingCount = rootHeaderCt.getVisibleGridColumns().length - 1; if (me.flex) { me.savedWidth = me.getWidth(); me.flex = null; } } rootHeaderCt.beginChildHide(); Ext.suspendLayouts(); if (owner.isGroupHeader) { if (me.isNestedGroupHeader()) { owner.hide(); } if (me.isSubHeader && !me.isGroupHeader && owner.query('>:not([hidden])').length === 1) { owner.lastCheckedHeaderId = me.id; } } me.callParent(); rootHeaderCt.endChildHide(); rootHeaderCt.onHeaderHide(me); Ext.resumeLayouts(true); return me; }, show: function() { var me = this, rootHeaderCt = me.getRootHeaderCt(), ownerCt = me.ownerCt; if (me.isVisible()) { return me; } if (me.rendered) { if (rootHeaderCt.forceFit) { rootHeaderCt.applyForceFit(me); } } Ext.suspendLayouts(); if (me.isSubHeader && ownerCt.hidden) { ownerCt.show(false, true); } me.callParent(arguments); if (me.isGroupHeader) { me.maybeShowNestedGroupHeader(); } ownerCt = me.getRootHeaderCt(); if (ownerCt) { ownerCt.onHeaderShow(me); } Ext.resumeLayouts(true); return me; }, getCellWidth: function() { var me = this, result; if (me.rendered && me.componentLayout && me.componentLayout.lastComponentSize) { result = me.componentLayout.lastComponentSize.width; } else if (me.width) { result = me.width; } else if (!me.isColumn) { result = me.getTableWidth(); } return result; }, getCellId: function() { return Ext.baseCSSPrefix + 'grid-cell-' + this.getItemId(); }, getCellSelector: function() { return '.' + this.getCellId(); }, getCellInnerSelector: function() { return this.getCellSelector() + ' .' + Ext.baseCSSPrefix + 'grid-cell-inner'; }, isAtStartEdge: function(e) { return (e.getXY()[0] - this.getX() < this.handleWidth); }, isAtEndEdge: function(e, margin) { return (this.getX() + this.getWidth() - e.getXY()[0] <= (margin || this.handleWidth)); }, setMenuActive: function(menu) { this.activeMenu = menu; this.titleEl[menu ? 'addCls' : 'removeCls'](this.headerOpenCls); }, deprecated: { 5: { methods: { bindRenderer: function(renderer) { return function(value) { return Ext.util.Format[renderer](value); }; } } } } }); Ext.define('Ext.tree.Column', { extend: 'Ext.grid.column.Column', alias: 'widget.treecolumn', tdCls: Ext.baseCSSPrefix + 'grid-cell-treecolumn', autoLock: true, lockable: false, draggable: false, hideable: false, iconCls: Ext.baseCSSPrefix + 'tree-icon', checkboxCls: Ext.baseCSSPrefix + 'tree-checkbox', elbowCls: Ext.baseCSSPrefix + 'tree-elbow', expanderCls: Ext.baseCSSPrefix + 'tree-expander', textCls: Ext.baseCSSPrefix + 'tree-node-text', innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-treecolumn', isTreeColumn: true, cellTpl: [ '', 'lineempty" role="presentation"/>', '', '-end-plus {expanderCls}" role="presentation"/>', '', ' {checkboxCls}-checked"/>', '', 'leafparent {iconCls}"', 'style="background-image:url({icon})"/>', '', '{value}', '', '{value}', '' ], initComponent: function() { var me = this; me.setupRenderer(); me.innerRenderer = me.renderer; me.renderer = me.treeRenderer; me.scope = me; me.callParent(); me.hasCustomRenderer = me.innerRenderer && me.innerRenderer.length > 1; }, treeRenderer: function(value, metaData, record, rowIdx, colIdx, store, view) { var me = this, cls = record.get('cls'), rendererData; if (metaData && cls) { metaData.tdCls += ' ' + cls; } rendererData = me.initTemplateRendererData(value, metaData, record, rowIdx, colIdx, store, view); return me.getTpl('cellTpl').apply(rendererData); }, initTemplateRendererData: function(value, metaData, record, rowIdx, colIdx, store, view) { var me = this, innerRenderer = me.innerRenderer, data = record.data, parent = record.parentNode, rootVisible = view.rootVisible, lines = [], parentData; while (parent && (rootVisible || parent.data.depth > 0)) { parentData = parent.data; lines[rootVisible ? parentData.depth : parentData.depth - 1] = parentData.isLast ? 0 : 1; parent = parent.parentNode; } return { record: record, baseIconCls: me.iconCls, iconCls: data.iconCls, icon: data.icon, checkboxCls: me.checkboxCls, checked: data.checked, elbowCls: me.elbowCls, expanderCls: me.expanderCls, textCls: me.textCls, leaf: data.leaf, expandable: record.isExpandable(), isLast: record.isLastVisible(), blankUrl: Ext.BLANK_IMAGE_URL, href: data.href, hrefTarget: data.hrefTarget, lines: lines, metaData: metaData, childCls: me.getChildCls ? me.getChildCls() + ' ' : '', value: innerRenderer ? innerRenderer.apply(me.rendererScope, arguments) : value }; } }); Ext.define('Ext.grid.NavigationModel', { extend: 'Ext.view.NavigationModel', alias: 'view.navigation.grid', focusCls: Ext.baseCSSPrefix + 'grid-item-focused', getViewListeners: function() { var me = this; return { containermousedown: me.onContainerMouseDown, cellmousedown: me.onCellMouseDown, cellclick: me.onCellClick, itemmousedown: me.onItemMouseDown, itemclick: me.onItemClick, itemcontextmenu: me.onItemClick, scope: me }; }, initKeyNav: function(view) { var me = this; me.position = new Ext.grid.CellContext(view); me.keyNav = new Ext.util.KeyNav({ target: view, ignoreInputFields: true, eventName: 'itemkeydown', defaultEventAction: 'stopEvent', processEvent: function(view, record, row, recordIndex, event) { return event; }, up: me.onKeyUp, down: me.onKeyDown, right: me.onKeyRight, left: me.onKeyLeft, pageDown: me.onKeyPageDown, pageUp: me.onKeyPageUp, home: me.onKeyHome, end: me.onKeyEnd, tab: me.onKeyTab, space: me.onKeySpace, enter: me.onKeyEnter, A: { ctrl: true, handler: me.onSelectAllKeyPress }, scope: me }); }, onKeyTab: function(keyEvent) { var view = keyEvent.position.view, selModel = view.getSelectionModel(), editingPlugin = view.editingPlugin; if (editingPlugin && selModel.wasEditing) { keyEvent.preventDefault(); selModel.onEditorTab(editingPlugin, keyEvent); } else { return this.callParent([ keyEvent ]); } }, onCellMouseDown: function(view, cell, cellIndex, record, row, recordIndex, mousedownEvent) { var parentEvent = mousedownEvent.parentEvent, cmp = Ext.Component.fromElement(mousedownEvent.target, cell); if (cmp && cmp.isFocusable && cmp.isFocusable()) { return; } if (!parentEvent || parentEvent.type !== 'touchstart') { this.setPosition(mousedownEvent.position, null, mousedownEvent); } }, onCellClick: function(view, cell, cellIndex, record, row, recordIndex, clickEvent) { var cmp = Ext.Component.fromElement(clickEvent.target, cell); this.preventCellFocus = cmp && cmp.focusable && cmp.isFocusable(); if (this.position.isEqual(clickEvent.position)) { this.fireNavigateEvent(clickEvent); } else { this.setPosition(clickEvent.position, null, clickEvent); } this.preventCellFocus = false; }, onItemMouseDown: function(view, record, item, index, mousedownEvent) { var me = this, x, columns, len, i, column, b, parentEvent = mousedownEvent.parentEvent; if (!parentEvent || parentEvent.type !== 'touchstart') { if (!mousedownEvent.position.cellElement) { x = mousedownEvent.getX(); columns = view.getVisibleColumnManager().getColumns(); len = columns.length; for (i = 0; i < len; i++) { column = columns[i]; b = columns[i].getBox(); if (x >= b.left && x < b.right) { me.setPosition(record, columns[i], mousedownEvent); return; } } } } }, onItemClick: function(view, record, item, index, clickEvent) { if (!clickEvent.position.cellElement) { this.fireNavigateEvent(clickEvent); } }, beforeViewRefresh: function(view) { var position = this.getPosition(); if (position && position.view === view) { this.focusRestorePosition = position.clone(); } else { this.focusRestorePosition = null; } }, onStoreRemove: function() { if (this.position) { this.setPosition(this.getPosition(), null, null, null, true); } }, deferSetPosition: function(delay, recordIndex, columnIndex, keyEvent, suppressEvent, preventNavigation) { var setPositionTask = this.view.getFocusTask(); setPositionTask.delay(delay, this.setPosition, this, [ recordIndex, columnIndex, keyEvent, suppressEvent, preventNavigation ]); return setPositionTask; }, setPosition: function(recordIndex, columnIndex, keyEvent, suppressEvent, preventNavigation) { var me = this, view, selModel, dataSource, newRecordIndex, newColumnIndex, newRecord, newColumn, clearing = recordIndex == null && columnIndex == null, isClear = me.record == null && me.recordIndex == null && me.item == null; if (recordIndex && recordIndex.isCellContext) { view = recordIndex.view; } else if (keyEvent && keyEvent.view) { view = keyEvent.view; } else if (me.lastFocused) { view = me.lastFocused.view; } else { view = me.view; } selModel = view.getSelectionModel(); dataSource = view.dataSource; view.getFocusTask().cancel(); if (view.isDestroyed || !view.refreshCounter || clearing && isClear || !view.all.getCount()) { return; } if (recordIndex && recordIndex.isCellContext) { newRecord = recordIndex.record; newRecordIndex = recordIndex.rowIdx; newColumnIndex = recordIndex.colIdx; newColumn = recordIndex.column; if (dataSource.indexOf(newRecord) === -1) { newRecordIndex = dataSource.indexOfId(newRecord.id); if (newRecordIndex === -1) { me.recordIndex = -1; newRecord = dataSource.getAt(0); newRecordIndex = 0; newColumnIndex = 0; newColumn = view.getVisibleColumnManager().getColumns()[0]; } else { newRecord = dataSource.getById(newRecord.id); } } } else { if (clearing) { newRecord = newRecordIndex = null; } else { if (columnIndex == null) { columnIndex = me.lastFocused ? me.lastFocused.column : 0; } if (typeof recordIndex === 'number') { newRecordIndex = Math.max(Math.min(recordIndex, dataSource.getCount() - 1), 0); newRecord = dataSource.getAt(recordIndex); } else if (recordIndex.isEntity) { newRecord = recordIndex; newRecordIndex = dataSource.indexOf(newRecord); } else if (recordIndex.tagName) { newRecord = view.getRecord(recordIndex); newRecordIndex = dataSource.indexOf(newRecord); if (newRecordIndex === -1) { newRecord = null; } } else { if (isClear) { return; } clearing = true; newRecord = newRecordIndex = null; } } if (newRecord) { if (newRecordIndex === -1) { me.recordIndex = -1; newRecord = dataSource.getAt(0); newRecordIndex = 0; columnIndex = null; } if (columnIndex == null) { if (!(newColumn = me.column)) { newColumnIndex = 0; newColumn = view.getVisibleColumnManager().getColumns()[0]; } } else if (typeof columnIndex === 'number') { newColumn = view.getVisibleColumnManager().getColumns()[columnIndex]; newColumnIndex = columnIndex; } else { newColumn = columnIndex; newColumnIndex = view.getVisibleColumnManager().indexOf(columnIndex); } } else { clearing = true; newColumn = newColumnIndex = null; } } if (newRecordIndex === me.recordIndex && newColumnIndex === me.columnIndex) { return me.focusPosition(me.position); } if (me.cell) { me.cell.removeCls(me.focusCls); } me.previousRecordIndex = me.recordIndex; me.previousRecord = me.record; me.previousItem = me.item; me.previousCell = me.cell; me.previousColumn = me.column; me.previousColumnIndex = me.columnIndex; me.previousPosition = me.position.clone(); me.selectionStart = selModel.selectionStart; me.position.setAll(view, me.recordIndex = newRecordIndex, me.columnIndex = newColumnIndex, me.record = newRecord, me.column = newColumn); if (clearing) { me.item = me.cell = null; } else { me.focusPosition(me.position, preventNavigation); } if (!suppressEvent) { selModel.fireEvent('focuschange', selModel, me.previousRecord, me.record); view.fireEvent('rowfocus', me.record, me.item, me.recordIndex); view.fireEvent('cellfocus', me.record, me.cell, me.position); } if (keyEvent && !preventNavigation && me.cell !== me.previousCell) { me.fireNavigateEvent(keyEvent); } }, focusPosition: function(position) { var me = this, view, row; me.item = me.cell = null; if (position && position.record && position.column) { view = position.view; if (position.rowElement) { row = me.item = position.rowElement; } else { row = view.getRowByRecord(position.record); } if (row) { me.cell = position.cellElement || Ext.fly(row).down(position.column.getCellSelector(), true); if (me.cell) { me.cell = new Ext.dom.Fly(me.cell); view.lastFocused = me.lastFocused = me.position.clone(); me.focusItem(me.cell); view.focusEl = me.cell; } else { me.position.setAll(); me.record = me.column = me.recordIndex = me.columnIndex = null; } } else { row = view.dataSource.indexOf(position.record); me.position.setAll(); me.record = me.column = me.recordIndex = me.columnIndex = null; if (row !== -1 && view.bufferedRenderer) { me.lastKeyEvent = null; view.bufferedRenderer.scrollTo(row, false, me.afterBufferedScrollTo, me); } } } }, focusItem: function(item) { item.addCls(this.focusCls); if (!this.preventCellFocus) { item.focus(); } }, getCell: function() { return this.cell; }, getPosition: function() { var me = this, position = me.position, curIndex, view, dataSource; if (position.record && position.column) { view = position.view; dataSource = view.dataSource; curIndex = dataSource.indexOf(position.record); if (curIndex === -1) { curIndex = position.rowIdx; if (!dataSource.getAt(curIndex)) { curIndex = -1; } } if (curIndex === -1 || view.getVisibleColumnManager().indexOf(position.column) === -1) { position.setAll(); me.record = me.column = me.recordIndex = me.columnIndex = null; } else { return position; } } return null; }, getLastFocused: function() { var me = this, view, lastFocused = me.lastFocused; if (lastFocused && lastFocused.record && lastFocused.column) { view = lastFocused.view; if (view.dataSource.indexOf(lastFocused.record) !== -1 && view.getVisibleColumnManager().indexOf(lastFocused.column) !== -1) { return lastFocused; } } }, onKeyUp: function(keyEvent) { var newRecord = keyEvent.view.walkRecs(keyEvent.record, -1); if (newRecord) { this.setPosition(newRecord, this.columnIndex, keyEvent); } }, onKeyDown: function(keyEvent) { var newRecord = keyEvent.record.isExpandingOrCollapsing ? null : keyEvent.view.walkRecs(keyEvent.record, 1); if (newRecord) { this.setPosition(newRecord, this.columnIndex, keyEvent); } }, onKeyRight: function(keyEvent) { var newPosition = this.move('right', keyEvent); if (newPosition) { this.setPosition(newPosition, null, keyEvent); } }, onKeyLeft: function(keyEvent) { var newPosition = this.move('left', keyEvent); if (newPosition) { this.setPosition(newPosition, null, keyEvent); } }, move: function(dir, keyEvent) { var me = this, position = me.getPosition(); if (position && position.record) { return position.view.walkCells(position, dir, null, me.preventWrap); } return null; }, onKeyPageDown: function(keyEvent) { var me = this, view = keyEvent.view, rowsVisible = me.getRowsVisible(), newIdx, newRecord; if (rowsVisible) { if (view.bufferedRenderer) { newIdx = Math.min(keyEvent.recordIndex + rowsVisible, view.dataSource.getCount() - 1); me.lastKeyEvent = keyEvent; view.bufferedRenderer.scrollTo(newIdx, false, me.afterBufferedScrollTo, me); } else { newRecord = view.walkRecs(keyEvent.record, rowsVisible); me.setPosition(newRecord, null, keyEvent); } } }, onKeyPageUp: function(keyEvent) { var me = this, view = keyEvent.view, rowsVisible = me.getRowsVisible(), newIdx, newRecord; if (rowsVisible) { if (view.bufferedRenderer) { newIdx = Math.max(keyEvent.recordIndex - rowsVisible, 0); me.lastKeyEvent = keyEvent; view.bufferedRenderer.scrollTo(newIdx, false, me.afterBufferedScrollTo, me); } else { newRecord = view.walkRecs(keyEvent.record, -rowsVisible); me.setPosition(newRecord, null, keyEvent); } } }, onKeyHome: function(keyEvent) { var me = this, view = keyEvent.view; if (keyEvent.altKey) { if (view.bufferedRenderer) { me.lastKeyEvent = keyEvent; view.bufferedRenderer.scrollTo(0, false, me.afterBufferedScrollTo, me); } else { me.setPosition(view.walkRecs(keyEvent.record, -view.dataSource.indexOf(keyEvent.record)), null, keyEvent); } } else { me.setPosition(keyEvent.record, 0, keyEvent); } }, afterBufferedScrollTo: function(newIdx, newRecord) { this.setPosition(newRecord, null, this.lastKeyEvent, null, !this.lastKeyEvent); }, onKeyEnd: function(keyEvent) { var me = this, view = keyEvent.view; if (keyEvent.altKey) { if (view.bufferedRenderer) { me.lastKeyEvent = keyEvent; view.bufferedRenderer.scrollTo(view.store.getCount() - 1, false, me.afterBufferedScrollTo, me); } else { me.setPosition(view.walkRecs(keyEvent.record, view.dataSource.getCount() - 1 - view.dataSource.indexOf(keyEvent.record)), null, keyEvent); } } else { me.setPosition(keyEvent.record, keyEvent.view.getVisibleColumnManager().getColumns().length - 1, keyEvent); } }, getRowsVisible: function() { var rowsVisible = false, view = this.view, firstRow = view.all.first(), rowHeight, gridViewHeight; if (firstRow) { rowHeight = firstRow.getHeight(); gridViewHeight = view.el.getHeight(); rowsVisible = Math.floor(gridViewHeight / rowHeight); } return rowsVisible; }, fireNavigateEvent: function(keyEvent) { var me = this; me.fireEvent('navigate', { view: me.position.view, navigationModel: me, keyEvent: keyEvent || new Ext.event.Event({}), previousPosition: me.previousPosition, previousRecordIndex: me.previousRecordIndex, previousRecord: me.previousRecord, previousItem: me.previousItem, previousCell: me.previousCell, previousColumnIndex: me.previousColumnIndex, previousColumn: me.previousColumn, position: me.position, recordIndex: me.recordIndex, record: me.record, selectionStart: me.selectionStart, item: me.item, cell: me.cell, columnIndex: me.columnIndex, column: me.column }); } }); Ext.define('Ext.tree.NavigationModel', { extend: 'Ext.grid.NavigationModel', alias: 'view.navigation.tree', initKeyNav: function(view) { var me = this, columns = me.view.ownerGrid.columns; me.isTreeGrid = columns && columns.length > 1; me.callParent([ view ]); me.keyNav.map.addBinding([ { key: '8', shift: true, handler: me.onAsterisk, scope: me }, { key: Ext.event.Event.NUM_MULTIPLY, handler: me.onAsterisk, scope: me } ]); me.view.grid.on({ columnschanged: me.onColumnsChanged, scope: me }); }, onColumnsChanged: function() { this.isTreeGrid = this.view.ownerGrid.getVisibleColumnManager().getColumns().length > 1; }, onKeyLeft: function(keyEvent) { var me = this, view = keyEvent.view, record = me.record; if (me.isTreeGrid && !keyEvent.ctrlKey) { return me.callParent([ keyEvent ]); } if (keyEvent.position.column.isTreeColumn && record.isExpanded()) { view.collapse(record); } else { record = record.parentNode; if (record && !(record.isRoot() && !view.rootVisible)) { me.setPosition(record, null, keyEvent); } } }, onKeyRight: function(keyEvent) { var me = this, record = me.record; if (me.isTreeGrid && !keyEvent.ctrlKey) { return me.callParent([ keyEvent ]); } if (!record.isLeaf()) { if (keyEvent.position.column.isTreeColumn && !record.isExpanded()) { keyEvent.view.expand(record); } else if (record.isExpanded()) { record = record.childNodes[0]; if (record) { me.setPosition(record); } } } }, onKeyEnter: function(keyEvent) { if (this.record.data.checked != null) { this.toggleCheck(keyEvent); } else { this.callParent([ keyEvent ]); } }, onKeySpace: function(keyEvent) { if (this.record.data.checked != null) { this.toggleCheck(keyEvent); } else { this.callParent([ keyEvent ]); } }, toggleCheck: function(keyEvent) { this.view.onCheckChange(this.record); }, onAsterisk: function(keyEvent) { this.view.ownerCt.expandAll(); } }); 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', 'Ext.data.TreeStore', 'Ext.tree.NavigationModel' ], viewType: 'treeview', treeCls: Ext.baseCSSPrefix + 'tree-panel', rowLines: false, lines: true, useArrows: false, singleExpand: false, ddConfig: { enableDrag: true, enableDrop: true }, rootVisible: true, displayField: 'text', root: null, normalCfgCopy: [ 'displayField', 'root', 'singleExpand', 'useArrows', 'lines', 'rootVisible', 'scroll' ], lockedCfgCopy: [ 'displayField', 'root', 'singleExpand', 'useArrows', 'lines', 'rootVisible' ], isTree: true, arrowCls: Ext.baseCSSPrefix + 'tree-arrows', linesCls: Ext.baseCSSPrefix + 'tree-lines', noLinesCls: Ext.baseCSSPrefix + 'tree-no-lines', autoWidthCls: Ext.baseCSSPrefix + 'autowidth-table', constructor: function(config) { config = config || {}; if (config.animate === undefined) { config.animate = Ext.isBoolean(this.animate) ? this.animate : Ext.enableFx; } this.enableAnimations = config.animate; delete config.animate; this.callParent([ config ]); }, initComponent: function() { var me = this, cls = [ me.treeCls ], store = me.store, view; if (me.useArrows) { cls.push(me.arrowCls); me.lines = false; } if (me.lines) { cls.push(me.linesCls); } else if (!me.useArrows) { cls.push(me.noLinesCls); } if (Ext.isString(store)) { store = me.store = Ext.StoreMgr.lookup(store); } else if (!store || !store.isStore) { store = Ext.apply({ type: 'tree', root: me.root, fields: me.fields, model: me.model, proxy: 'memory', folderSort: me.folderSort }, store); store = me.store = Ext.StoreMgr.lookup(store); } else if (me.root) { store = me.store = Ext.data.StoreManager.lookup(store); store.setRoot(me.root); if (me.folderSort !== undefined) { store.folderSort = me.folderSort; store.sort(); } } store.setRootVisible(me.rootVisible); if (!store.getRoot()) { store.setRoot({}); } me.viewConfig = Ext.apply({ rootVisible: me.rootVisible, animate: me.enableAnimations, singleExpand: me.singleExpand, node: store.getRoot(), hideHeaders: me.hideHeaders, navigationModel: 'tree' }, me.viewConfig); if (!me.columns) { if (me.initialConfig.hideHeaders === undefined) { me.hideHeaders = true; } me.addCls(me.autoWidthCls); me.columns = [ { xtype: 'treecolumn', text: 'Name', flex: 1, dataIndex: me.displayField } ]; } if (me.cls) { cls.push(me.cls); } me.cls = cls.join(' '); me.callParent(); view = me.getView(); me.relayEvents(view, [ 'checkchange', 'afteritemexpand', 'afteritemcollapse' ]); }, bindStore: function(store, initial) { var me = this, root = store.getRoot(), bufferedRenderer = me.bufferedRenderer; me.callParent(arguments); if (bufferedRenderer) { if (bufferedRenderer.store) { bufferedRenderer.bindStore(store); } } store.singleExpand = me.singleExpand; me.storeListeners = me.mon(store, { destroyable: true, rootchange: me.onRootChange, scope: me }); me.storeRelayers = me.relayEvents(store, [ 'beforeload', 'load' ]); me.rootRelayers = me.mon(root, { destroyable: true, append: me.createRelayer('itemappend'), remove: me.createRelayer('itemremove'), move: me.createRelayer('itemmove', [ 0, 4 ]), insert: me.createRelayer('iteminsert'), beforeappend: me.createRelayer('beforeitemappend'), beforeremove: me.createRelayer('beforeitemremove'), beforemove: me.createRelayer('beforeitemmove'), beforeinsert: me.createRelayer('beforeiteminsert'), expand: me.createRelayer('itemexpand', [ 0, 1 ]), collapse: me.createRelayer('itemcollapse', [ 0, 1 ]), beforeexpand: me.createRelayer('beforeitemexpand', [ 0, 1 ]), beforecollapse: me.createRelayer('beforeitemcollapse', [ 0, 1 ]) }); if (!me.rootVisible && !store.autoLoad && !(root.isExpanded() || root.isLoading())) { if (root.isLoaded()) { root.data.expanded = true; store.onNodeExpand(root, root.childNodes); } else if (store.autoLoad !== false) { root.data.expanded = false; root.expand(); } } store.ownerTree = me; if (!initial) { me.view.setRootNode(root); } }, unbindStore: function() { var me = this, store = me.store; if (store) { me.callParent(); Ext.destroy(me.storeListeners, me.storeRelayers, me.rootRelayers); delete store.ownerTree; store.singleExpand = null; } }, setRootNode: function() { return this.store.setRoot.apply(this.store, arguments); }, getRootNode: function() { return this.store.getRoot(); }, onRootChange: function(root) { this.view.setRootNode(root); }, getChecked: function() { return this.getView().getChecked(); }, isItemChecked: function(rec) { return rec.get('checked'); }, expandNode: function(record, deep, callback, scope) { return this.getView().expand(record, deep, callback, scope || this); }, collapseNode: function(record, deep, callback, scope) { return this.getView().collapse(record, deep, callback, scope || this); }, expandAll: function(callback, scope) { var me = this, root = me.getRootNode(); if (root) { Ext.suspendLayouts(); root.expand(true, callback, scope || me); Ext.resumeLayouts(true); } }, collapseAll: function(callback, scope) { var me = this, root = me.getRootNode(), view = me.getView(); if (root) { Ext.suspendLayouts(); scope = scope || me; if (view.rootVisible) { root.collapse(true, callback, scope); } else { root.collapseChildren(true, callback, scope); } Ext.resumeLayouts(true); } }, expandPath: function(path, options) { var args = arguments, me = this, view = me.view, field = (options && options.field) || me.store.model.idProperty, select, doFocus, separator = (options && options.separator) || '/', callback, scope, current, index, keys, rooted, expander; if (options && typeof options === 'object') { field = options.field || me.store.model.idProperty; separator = options.separator || '/'; callback = options.callback; scope = options.scope; select = options.select; doFocus = options.focus; } else { field = args[1] || me.store.model.idProperty; separator = args[2] || '/'; callback = args[3]; scope = args[4]; } if (Ext.isEmpty(path)) { return Ext.callback(callback, scope || me, [ false, null ]); } keys = path.split(separator); rooted = !keys[0]; if (rooted) { current = me.getRootNode(); index = 1; } else { current = me.store.findNode(field, keys[0]); index = 0; } if (!current || (rooted && current.get(field) !== keys[1])) { return Ext.callback(callback, scope || me, [ false, current ]); } expander = function(newChildren) { var node = this, len, i, value; if (++index === keys.length) { if (select) { view.getSelectionModel().select(node); } if (doFocus) { view.getNavigationModel().setPosition(node, 0); } return Ext.callback(callback, scope || me, [ true, node, view.getNode(node) ]); } for (i = 0 , len = newChildren ? newChildren.length : 0; i < len; i++) { node = newChildren[i]; value = node.get(field); if (value || value === 0) { value = value.toString(); } if (value === keys[index]) { return node.expand(false, expander); } } node = this; Ext.callback(callback, scope || me, [ false, node, view.getNode(node) ]); }; current.expand(false, expander); }, ensureVisible: function(path, options) { if (path.isEntity) { return this.callParent([ path, options ]); } var me = this, field = (options && options.field) || me.store.model.idProperty, separator = (options && options.separator) || '/', callback, scope, keys, rooted, last, node, parentNode, onLastExpanded = function(success, lastExpanded, lastExpandedHtmlNode, targetNode) { if (!targetNode && success && lastExpanded) { targetNode = lastExpanded.findChild(field, last); } if (targetNode) { me.doEnsureVisible(targetNode, options); } else { Ext.callback(callback, scope || me, [ false, lastExpanded ]); } }; if (options) { callback = options.callback; scope = options.scope; } keys = path.split(separator); rooted = !keys[0]; last = keys.pop(); if (keys.length && !(rooted && keys.length === 1)) { me.expandPath(keys.join(separator), field, separator, onLastExpanded); } else { node = me.store.findNode(field, last); if (node) { parentNode = node.parentNode; if (parentNode && !parentNode.isExpanded()) { parentNode.expand(); } onLastExpanded(true, null, null, node); } else { Ext.callback(callback, scope || me, [ false, null ]); } } }, selectPath: function(path, field, separator, callback, scope) { this.ensureVisible(path, { field: field, separator: separator, select: true, callback: callback, scope: scope }); } }); Ext.define('Ext.form.field.VTypes', (function() { var alpha = /^[a-zA-Z_]+$/, alphanum = /^[a-zA-Z0-9_]+$/, email = /^(")?(?:[^\."])(?:(?:[\.])?(?:[\w\-!#$%&'*+/=?^_`{|}~]))*\1@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/, url = /(((^https?)|(^ftp)):\/\/((([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*)|(localhost|LOCALHOST))\/?)/i; return { singleton: true, alternateClassName: 'Ext.form.VTypes', 'email': function(value) { return email.test(value); }, 'emailText': 'This field should be an e-mail address in the format "user@example.com"', 'emailMask': /[\w.\-@'"!#$%&'*+/=?^_`{|}~]/i, 'url': function(value) { return url.test(value); }, 'urlText': 'This field should be a URL in the format "http:/' + '/www.example.com"', 'alpha': function(value) { return alpha.test(value); }, 'alphaText': 'This field should only contain letters and _', 'alphaMask': /[a-z_]/i, 'alphanum': function(value) { return alphanum.test(value); }, 'alphanumText': 'This field should only contain letters, numbers and _', 'alphanumMask': /[a-z0-9_]/i }; }())); Ext.define('Ext.form.trigger.Trigger', { alias: 'trigger.trigger', requires: [ 'Ext.util.ClickRepeater' ], mixins: [ 'Ext.mixin.Factoryable' ], factoryConfig: { defaultType: 'trigger' }, repeatClick: false, hidden: false, hideOnReadOnly: undefined, weight: 0, preventMouseDown: true, baseCls: Ext.baseCSSPrefix + 'form-trigger', focusCls: Ext.baseCSSPrefix + 'form-trigger-focus', overCls: Ext.baseCSSPrefix + 'form-trigger-over', clickCls: Ext.baseCSSPrefix + 'form-trigger-click', validIdRe: Ext.validIdRe, renderTpl: [ '
style="{triggerStyle}">', '{[values.$trigger.renderBody(values)]}', '
' ], statics: { weightComparator: function(triggerA, triggerB) { return triggerA.weight - triggerB.weight; } }, constructor: function(config) { var me = this, cls; Ext.apply(me, config); if (me.compat4Mode) { cls = me.cls; me.focusCls = [ me.focusCls, cls + '-focus' ]; me.overCls = [ me.overCls, cls + '-over' ]; me.clickCls = [ me.clickCls, cls + '-click' ]; } if (!me.validIdRe.test(me.id)) { Ext.Error.raise('Invalid trigger "id": "' + me.id + '"'); } }, afterFieldRender: function() { this.initEvents(); }, destroy: function() { var me = this, clickRepeater = me.clickRepeater; if (clickRepeater) { clickRepeater.destroy(); } if (me.el) { me.el.destroy(); } me.el = null; me.isDestroyed = true; }, getBodyRenderData: Ext.emptyFn, getEl: function() { return this.el || null; }, getStateEl: function() { return this.el; }, hide: function() { var me = this, el = me.el; me.hidden = true; if (el) { el.hide(); } }, initEvents: function() { var me = this, isFieldEnabled = me.isFieldEnabled, stateEl = me.getStateEl(), el = me.el; stateEl.addClsOnOver(me.overCls, isFieldEnabled, me); stateEl.addClsOnClick(me.clickCls, isFieldEnabled, me); if (me.repeatClick) { me.clickRepeater = new Ext.util.ClickRepeater(el, { preventDefault: true, handler: me.onClick, listeners: { mousedown: me.onClickRepeaterMouseDown, scope: me }, scope: me }); } else { me.field.mon(el, { click: me.onClick, mousedown: me.onMouseDown, scope: me }); } }, isFieldEnabled: function() { return !this.field.disabled; }, isVisible: function() { var me = this, field = me.field, hidden = false; if (me.hidden || !field || !me.rendered || me.isDestroyed) { hidden = true; } return !hidden; }, onClick: function() { var me = this, args = arguments, e = me.clickRepeater ? args[1] : args[0], handler = me.handler, field = me.field; if (handler && !field.readOnly && me.isFieldEnabled()) { Ext.callback(me.handler, me.scope, [ field, me, e ], 0, field); } }, resolveListenerScope: function(scope) { return this.field.resolveSatelliteListenerScope(this, scope); }, onMouseDown: function(e) { if (e.pointerType !== 'touch' && !this.field.owns(Ext.Element.getActiveElement())) { this.field.inputEl.focus(); } if (this.preventMouseDown) { e.preventDefault(); } }, onClickRepeaterMouseDown: function(clickRepeater, e) { if (!e.parentEvent || e.parentEvent.type === 'mousedown') { this.field.inputEl.focus(); } e.preventDefault(); }, onFieldBlur: function() { this.getStateEl().removeCls(this.focusCls); }, onFieldFocus: function() { this.getStateEl().addCls(this.focusCls); }, onFieldRender: function() { var me = this, el = me.el = me.field.triggerWrap.selectNode('#' + me.domId, false); el.setVisibilityMode(Ext.Element.DISPLAY); me.rendered = true; }, renderBody: function(renderData) { var me = this, bodyTpl = me.bodyTpl; Ext.apply(renderData, me.getBodyRenderData()); return bodyTpl ? Ext.XTemplate.getTpl(me, 'bodyTpl').apply(renderData) : ''; }, renderTrigger: function(fieldData) { var me = this, width = me.width, triggerStyle = me.hidden ? 'display:none;' : ''; if (width) { triggerStyle += 'width:' + width; } return Ext.XTemplate.getTpl(me, 'renderTpl').apply({ $trigger: me, fieldData: fieldData, ui: fieldData.ui, childElCls: fieldData.childElCls, triggerId: me.domId = me.field.id + '-trigger-' + me.id, cls: me.cls, triggerStyle: triggerStyle, extraCls: me.extraCls, baseCls: me.baseCls }); }, setHidden: function(hidden) { if (hidden !== this.hidden) { this[hidden ? 'hide' : 'show'](); } }, setVisible: function(visible) { this.setHidden(!visible); }, show: function() { var me = this, el = me.el; me.hidden = false; if (el) { el.show(); } } }); Ext.define('Ext.form.field.Text', { extend: 'Ext.form.field.Base', alias: 'widget.textfield', requires: [ 'Ext.form.field.VTypes', 'Ext.form.trigger.Trigger', 'Ext.util.TextMetrics' ], alternateClassName: [ 'Ext.form.TextField', 'Ext.form.Text' ], config: { hideTrigger: false, triggers: undefined }, growMin: 30, growMax: 800, growAppend: 'W', allowBlank: true, validateBlank: false, allowOnlyWhitespace: true, minLength: 0, maxLength: Number.MAX_VALUE, minLengthText: 'The minimum length for this field is {0}', maxLengthText: 'The maximum length for this field is {0}', blankText: 'This field is required', regexText: '', emptyCls: Ext.baseCSSPrefix + 'form-empty-field', requiredCls: Ext.baseCSSPrefix + 'form-required-field', valueContainsPlaceholder: false, ariaRole: 'textbox', editable: true, repeatTriggerClick: false, triggerWrapCls: Ext.baseCSSPrefix + 'form-trigger-wrap', triggerWrapFocusCls: Ext.baseCSSPrefix + 'form-trigger-wrap-focus', triggerWrapInvalidCls: Ext.baseCSSPrefix + 'form-trigger-wrap-invalid', fieldBodyCls: Ext.baseCSSPrefix + 'form-text-field-body', inputWrapCls: Ext.baseCSSPrefix + 'form-text-wrap', inputWrapFocusCls: Ext.baseCSSPrefix + 'form-text-wrap-focus', inputWrapInvalidCls: Ext.baseCSSPrefix + 'form-text-wrap-invalid', growCls: Ext.baseCSSPrefix + 'form-text-grow', monitorTab: true, mimicing: false, needArrowKeys: true, childEls: [ 'triggerWrap', 'inputWrap' ], preSubTpl: [ '
', '
' ], postSubTpl: [ '
', '{[values.renderTrigger(parent)]}', '
' ], initComponent: function() { var me = this, emptyCls = me.emptyCls; if (me.allowOnlyWhitespace === false) { me.allowBlank = false; } if (me.size) { Ext.log.warn('Ext.form.field.Text "size" config was deprecated in Ext 5.0. Please specify a "width" or use a layout instead.'); } if (me.size) { me.defaultBodyWidth = me.size * 6.5 + 20; } if (!me.onTrigger1Click) { me.onTrigger1Click = me.onTriggerClick; } me.callParent(); if (me.readOnly) { me.setReadOnly(me.readOnly); } me.fieldFocusCls = me.baseCls + '-focus'; me.emptyUICls = emptyCls + ' ' + emptyCls + '-' + me.ui; me.addStateEvents('change'); }, 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); } if (me.enableKeyEvents) { me.mon(el, { scope: me, keyup: me.onKeyUp, keydown: me.onKeyDown, keypress: me.onKeyPress }); } }, isEqual: function(value1, value2) { return this.isEqualAsString(value1, value2); }, onChange: function(newVal, oldVal) { this.callParent(arguments); this.autoSize(); }, getSubTplData: function(fieldData) { var me = this, value = me.getRawValue(), isEmpty = me.emptyText && value.length < 1, maxLength = me.maxLength, placeholder; if (me.enforceMaxLength) { if (maxLength === Number.MAX_VALUE) { maxLength = undefined; } } else { maxLength = undefined; } if (isEmpty) { if (Ext.supports.Placeholder) { placeholder = me.emptyText; } else { value = me.emptyText; me.valueContainsPlaceholder = true; } } return Ext.apply(me.callParent(arguments), { triggerWrapCls: me.triggerWrapCls, inputWrapCls: me.inputWrapCls, triggers: me.orderedTriggers, maxLength: maxLength, readOnly: !me.editable || me.readOnly, placeholder: placeholder, value: value, fieldCls: me.fieldCls + ((isEmpty && (placeholder || value)) ? ' ' + me.emptyUICls : '') + (me.allowBlank ? '' : ' ' + me.requiredCls) }); }, onRender: function() { var me = this, triggers = me.getTriggers(), elements = [], id, triggerEl; if (Ext.supports.FixedTableWidthBug) { me.el._needsTableWidthFix = true; } me.callParent(); if (triggers) { this.invokeTriggers('onFieldRender'); for (id in triggers) { elements.push(triggers[id].el); } triggerEl = me.triggerEl = me.triggerCell = new Ext.CompositeElement(elements, true); } me.inputCell = me.inputWrap; }, afterRender: function() { var me = this; me.autoSize(); me.callParent(); me.invokeTriggers('afterFieldRender'); }, onMouseDown: function() { var me = this; if (!me.hasFocus) { Ext.getDoc().on('mouseup', Ext.emptyFn, me, { single: true, preventDefault: true }); } }, applyTriggers: function(triggers) { var me = this, hideAllTriggers = me.getHideTrigger(), readOnly = me.readOnly, orderedTriggers = me.orderedTriggers = [], repeatTriggerClick = me.repeatTriggerClick, id, triggerCfg, trigger, triggerCls, i; if (me.rendered) { Ext.Error.raise("Cannot set triggers after field has already been rendered."); } if ((me.triggerCls && !triggers) || me.trigger1Cls) { Ext.log.warn("Ext.form.field.Text: 'triggerCls' and 'triggerCls'" + " are deprecated. Use 'triggers' instead."); } if (!triggers) { triggers = {}; if (me.triggerCls && !me.trigger1Cls) { me.trigger1Cls = me.triggerCls; } for (i = 1; triggerCls = me['trigger' + i + 'Cls']; i++) { triggers['trigger' + i] = { cls: triggerCls, extraCls: Ext.baseCSSPrefix + 'trigger-index-' + i, handler: 'onTrigger' + i + 'Click', compat4Mode: true, scope: me }; } } for (id in triggers) { if (triggers.hasOwnProperty(id)) { triggerCfg = triggers[id]; triggerCfg.field = me; triggerCfg.id = id; if ((readOnly && triggerCfg.hideOnReadOnly !== false) || (hideAllTriggers && triggerCfg.hidden !== false)) { triggerCfg.hidden = true; } if (repeatTriggerClick && (triggerCfg.repeatClick !== false)) { triggerCfg.repeatClick = true; } trigger = triggers[id] = Ext.form.trigger.Trigger.create(triggerCfg); orderedTriggers.push(trigger); } } Ext.Array.sort(orderedTriggers, Ext.form.trigger.Trigger.weightComparator); return triggers; }, invokeTriggers: function(methodName, args) { var me = this, triggers = me.getTriggers(), id, trigger; if (triggers) { for (id in triggers) { if (triggers.hasOwnProperty(id)) { trigger = triggers[id]; trigger[methodName].apply(trigger, args || []); } } } }, getTrigger: function(id) { return this.getTriggers()[id]; }, updateHideTrigger: function(hideTrigger) { this.invokeTriggers(hideTrigger ? 'hide' : 'show'); }, setEditable: function(editable) { var me = this; me.editable = editable; if (me.rendered) { me.setReadOnlyAttr(!editable || me.readOnly); } }, setReadOnly: function(readOnly) { var me = this, triggers = me.getTriggers(), hideTriggers = me.getHideTrigger(), trigger, id; readOnly = !!readOnly; me.callParent([ readOnly ]); if (me.rendered) { me.setReadOnlyAttr(readOnly || !me.editable); } if (triggers) { for (id in triggers) { trigger = triggers[id]; if (trigger.hideOnReadOnly === true || (trigger.hideOnReadOnly !== false && !hideTriggers)) { trigger.setVisible(!readOnly); } } } }, setReadOnlyAttr: function(readOnly) { var me = this, readOnlyName = 'readonly', inputEl = me.inputEl.dom; if (readOnly) { inputEl.setAttribute(readOnlyName, readOnlyName); } else { inputEl.removeAttribute(readOnlyName); } }, 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; }, onDisable: function() { this.callParent(); if (Ext.isIE) { this.inputEl.dom.unselectable = 'on'; } }, onEnable: function() { this.callParent(); if (Ext.isIE) { this.inputEl.dom.unselectable = ''; } }, onKeyDown: function(e) { this.fireEvent('keydown', this, e); }, onKeyUp: function(e) { this.fireEvent('keyup', this, e); }, onKeyPress: function(e) { this.fireEvent('keypress', this, e); }, 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); me.valueContainsPlaceholder = true; } if (isEmpty) { me.inputEl.addCls(me.emptyUICls); } else { me.inputEl.removeCls(me.emptyUICls); } me.autoSize(); } }, afterFirstLayout: function() { this.callParent(); if (Ext.isIE && this.disabled) { var el = this.inputEl; if (el) { el.dom.unselectable = 'on'; } } }, toggleInvalidCls: function(hasError) { var method = hasError ? 'addCls' : 'removeCls'; this.callParent(); this.triggerWrap[method](this.triggerWrapInvalidCls); this.inputWrap[method](this.inputWrapInvalidCls); }, beforeFocus: function() { var me = this, inputEl = me.inputEl, emptyText = me.emptyText, isEmpty; me.callParent(arguments); if ((emptyText && !Ext.supports.Placeholder) && (inputEl.dom.value === me.emptyText && me.valueContainsPlaceholder)) { me.setRawValue(''); isEmpty = true; inputEl.removeCls(me.emptyUICls); me.valueContainsPlaceholder = false; } else if (Ext.supports.Placeholder) { inputEl.removeCls(me.emptyUICls); } }, onFocus: function(e) { var me = this; me.callParent(arguments); if (me.selectOnFocus) { me.inputEl.dom.select(); } if (me.emptyText) { me.autoSize(); } me.addCls(me.fieldFocusCls); me.triggerWrap.addCls(me.triggerWrapFocusCls); me.inputWrap.addCls(me.inputWrapFocusCls); me.invokeTriggers('onFieldFocus', [ e ]); }, onBlur: function(e) { var me = this; me.callParent(arguments); me.removeCls(me.fieldFocusCls); me.triggerWrap.removeCls(me.triggerWrapFocusCls); me.inputWrap.removeCls(me.inputWrapFocusCls); me.invokeTriggers('onFieldBlur', [ e ]); }, completeEdit: function(e) { this.callParent([ e ]); this.applyEmptyText(); }, filterKeys: function(e) { if ((e.ctrlKey && !e.altKey) || e.isSpecialKey()) { return; } var charCode = String.fromCharCode(e.getCharCode()); if (!this.maskRe.test(charCode)) { e.stopEvent(); } }, getState: function() { return this.addPropertyToState(this.callParent(), 'value'); }, applyState: function(state) { this.callParent(arguments); if (state.hasOwnProperty('value')) { this.setValue(state.value); } }, getRawValue: function() { var me = this, v = me.callParent(); if (v === me.emptyText && me.valueContainsPlaceholder) { v = ''; } return v; }, setValue: function(value) { var me = this, inputEl = me.inputEl; if (inputEl && me.emptyText && !Ext.isEmpty(value)) { inputEl.removeCls(me.emptyUICls); me.valueContainsPlaceholder = false; } me.callParent(arguments); me.applyEmptyText(); return me; }, getErrors: function(value) { value = arguments.length ? (value == null ? '' : value) : this.processRawValue(this.getRawValue()); var me = this, errors = me.callParent([ value ]), validator = me.validator, vtype = me.vtype, vtypes = Ext.form.field.VTypes, regex = me.regex, format = Ext.String.format, msg, trimmed, isBlank; if (Ext.isFunction(validator)) { msg = validator.call(me, value); if (msg !== true) { errors.push(msg); } } trimmed = me.allowOnlyWhitespace ? value : Ext.String.trim(value); if (trimmed.length < 1 || (value === me.emptyText && me.valueContainsPlaceholder)) { if (!me.allowBlank) { errors.push(me.blankText); } if (!me.validateBlank) { return errors; } isBlank = true; } if (!isBlank && value.length < me.minLength) { errors.push(format(me.minLengthText, me.minLength)); } if (value.length > me.maxLength) { errors.push(format(me.maxLengthText, me.maxLength)); } if (vtype) { if (!vtypes[vtype](value, me)) { errors.push(me.vtypeText || vtypes[vtype + 'Text']); } } if (regex && !regex.test(value)) { errors.push(me.regexText || me.invalidText); } return errors; }, selectText: function(start, end) { var me = this, v = me.getRawValue(), len = v.length, el = me.inputEl.dom, range; if (len > 0) { start = start === undefined ? 0 : Math.min(start, len); end = end === undefined ? len : Math.min(end, len); if (el.setSelectionRange) { el.setSelectionRange(start, end); } else if (el.createTextRange) { range = el.createTextRange(); range.moveStart('character', start); range.moveEnd('character', end - len); range.select(); } } }, getGrowWidth: function() { return this.inputEl.dom.value; }, autoSize: function() { var me = this, triggers, triggerId, triggerWidth, inputEl, width, value; if (me.grow && me.rendered && me.getSizeModel().width.auto) { inputEl = me.inputEl; triggers = me.getTriggers(); triggerWidth = 0; value = Ext.util.Format.htmlEncode(me.getGrowWidth() || (me.hasFocus ? '' : me.emptyText) || ''); value += me.growAppend; for (triggerId in triggers) { triggerWidth += triggers[triggerId].el.getWidth(); } width = inputEl.getTextWidth(value) + triggerWidth + me.inputWrap.getBorderWidth('lr') + me.triggerWrap.getBorderWidth('lr'); width = Math.min(Math.max(width, me.growMin), me.growMax); me.bodyEl.setWidth(width); me.updateLayout(); me.fireEvent('autosize', me, width); } }, onDestroy: function() { var me = this; me.invokeTriggers('destroy'); Ext.destroy(me.triggerRepeater); me.callParent(); }, onTriggerClick: Ext.emptyFn, privates: { getTdType: function() { return 'textfield'; } }, deprecated: { 5: { methods: { getTriggerWidth: function() { var triggers = this.getTriggers(), width = 0, id; if (triggers && this.rendered) { for (id in triggers) { if (triggers.hasOwnProperty(id)) { width += triggers[id].el.getWidth(); } } } return width; } } } } }); Ext.define('Ext.app.bindinspector.ComponentList', { alias: 'widget.bindinspector-componentlist', extend: 'Ext.tree.Panel', requires: [ 'Ext.form.field.Text' ], rootVisible: false, title: 'Component Tree', hideHeaders: true, bindingsIconCls: Ext.baseCSSPrefix + 'bindings-icon', vmIconCls: Ext.baseCSSPrefix + 'vm-icon', missingDataCls: Ext.baseCSSPrefix + 'bindinspector-missing-data', filterVisibleCls: Ext.baseCSSPrefix + 'bindinspector-filter-visible', lastItemCls: Ext.baseCSSPrefix + 'bindinspector-last-item', bindingsIcon: '☍', vmIcon: '☶', initComponent: function() { var me = this, nodes = []; me.viewConfig = { toggleOnDblClick: false, getRowClass: function(record, index, rowParams, store) { var cls = []; if (record.get('filtervisible')) { cls.push(me.filterVisibleCls); } if (record.get('sansData')) { cls.push(me.missingDataCls); } if (index === store.getCount() - 1) { cls.push(me.lastItemCls); } return cls.join(' '); } }; Ext.Array.forEach(me.components, function(comp) { nodes.push(me.buildNode(comp)); }, me); me.store = { model: me.Model, root: { expanded: true, children: nodes } }; me.columns = [ { itemId: 'srcVMIndicator', width: 40, hidden: true, renderer: me.srcVMIndicator, scope: me }, { xtype: 'treecolumn', dataIndex: 'text', flex: 1 } ]; me.dockedItems = [ { xtype: 'toolbar', itemId: 'queryFieldTb', dock: 'top', items: [ { xtype: 'textfield', reference: 'queryField', itemId: 'queryField', emptyText: 'simple search by reference / ID or use a component query...', flex: 1, triggers: { clear: { cls: Ext.baseCSSPrefix + 'form-clear-trigger', handler: function(field) { var tree = field.up('treepanel'); field.reset(); tree.clearComponentFilter(); field.focus(); } } }, listeners: { change: { fn: me.filterComponentTree, buffer: 250, scope: me }, afterrender: { fn: function(field) { var tbEl = field.up('toolbar').getEl(); field.mon(tbEl, 'mouseenter', function() { var tip = me.bindingsTip, showAt, x, y; tip.stopAnimation(); tip.update('Simple Search
Enter the string matching the reference or ID of the target component
Component Query
Enter a component query string to find any items matching the query'); tip.setTarget(tbEl); tip.show(); x = tip.getX(); y = tip.getY(); showAt = tip.getAlignToXY(tbEl, 'l-r'); tip.animate({ from: { opacity: 0, x: showAt[0] + 20, y: showAt[1] }, to: { opacity: 1, x: showAt[0] + 10, y: showAt[1] } }); }); }, scope: me } } } ] }, { xtype: 'toolbar', cls: Ext.baseCSSPrefix + 'vm-results-tb', itemId: 'vmQueryResultsTb', hidden: true, dock: 'top', defaultButtonUI: 'default', items: [ '->', { text: 'Clear VM Filter', handler: function() { var tb = this.up('#vmQueryResultsTb'), componentList = tb.up('bindinspector-componentlist'), queryTb = componentList.down('#queryFieldTb'), queryField = queryTb.down('#queryField'); tb.hide(); queryTb.show(); componentList.clearVMSearchIndicators(); queryField.setValue(queryField.lastValue); componentList.filterComponentTree(null, queryField.lastValue); } } ] } ]; me.callParent(); me.getView().on('itemdblclick', me.onItemDblclick, me); me.on('select', me.onItemSelect, me); me.bindingsTip = Ext.create('Ext.tip.ToolTip', { renderTo: document.body, anchor: 'left', cls: Ext.baseCSSPrefix + 'componentlist-tip', bodyPadding: 12 }); me.getView().on('itemmouseenter', me.showBindingsTip, me); }, clearVMSearchIndicators: function() { var indicatedVM = this.indicatedVM; Ext.suspendLayouts(); if (indicatedVM) { Ext.Array.forEach(indicatedVM, function(rec) { rec.set('isSrcVM', false); }); } this.down('#srcVMIndicator').hide(); Ext.resumeLayouts(true); this.indicatedVM = null; }, srcVMIndicator: function(v, meta, rec) { var refVM = rec.get('isSrcVM'), tip = '', vmDetail, firstTierRec, firstTierName, targetRec; if (refVM) { vmDetail = this.up('bindinspector-container').down('bindinspector-viewmodeldetail'); firstTierRec = vmDetail.getFirstTierRec(refVM); firstTierName = firstTierRec.get('name'); if (firstTierRec !== refVM) { tip += 'Root data node:  ' + firstTierName + '
'; } targetRec = firstTierRec === refVM ? firstTierRec : refVM; tip += targetRec.get('name') + ':'; tip += '
    '; tip += '' + Ext.app.bindinspector.Util.valueRenderer(targetRec.get('value')) + ''; meta.tdCls = Ext.baseCSSPrefix + 'bindindicator-vm-src'; meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + tip + '"'; } }, onDestroy: function() { this.bindingsTip.destroy(); this.callParent(); }, showBindingsTip: function(view, record, item, index, e) { var me = this, tip = me.bindingsTip, sansData = record.get('sansData'), bindings, bindingText; tip.stopAnimation(); if (record.get('hasBindings')) { bindings = me.ownerCt.env.getCmp(record.get('id')).bindings; bindingText = []; Ext.Object.each(bindings, function(key, val, o) { var kv = key + ': ' + '' + val.descriptor + '
', bindValue = val.value, v; if (Ext.isString(bindValue)) { v = bindValue; } else if (Ext.isObject(bindValue)) { if (bindValue.isStore === true) { v = 'Store {' + bindValue.entityName + '}'; } else if (bindValue.isModel === true) { v = 'Model {' + bindValue.entityName + '}'; } } kv += '' + v + ''; bindingText.push(kv); }); bindingText = bindingText.join('
'); if (sansData) { bindingText += '
'; Ext.Array.forEach(sansData, function(missing) { bindingText += '
Missing data: ' + missing + '
'; }); } tip.update(bindingText); tip.setTarget(item); tip.show(); tip.alignTo(item, 'l-r', [ 20, 0 ]); tip.animate({ from: { opacity: 0 }, to: { opacity: 1, x: tip.getX() - 10 } }); } }, filterComponentTree: function(field, val) { var tree = this, field = tree.down('#queryField'), newVal = val || field.getValue(), store = tree.store, queryRe = /[\s>\[\]=()^'"~$@*:+#,]/g, valIsArray = Ext.isArray(newVal), ids = valIsArray ? newVal : [], components = [], isQuery, len, i; if (Ext.isString(newVal)) { isQuery = queryRe.test(Ext.String.trim(newVal)); } if (newVal.length > 0) { tree.filteredComponents = []; if (isQuery) { try { components = Ext.ComponentQuery.query(newVal); } catch (e) {} len = components.length; for (i = 0; i < len; i++) { ids.push(components[i].id); } } store.suspendEvents(); store.filter({ filterFn: function(node) { var children = node.childNodes, length = children && children.length, visible = false, j; if (isQuery || valIsArray) { visible = Ext.Array.contains(ids, node.get('id')); } else { visible = node.get('text').indexOf(newVal) > -1; } node.set('filtervisible', visible); if (visible) { tree.filteredComponents.push(node); } for (j = 0; j < length; j++) { if (children[j].get('visible')) { visible = true; } } return visible; }, id: 'queryFilter' }); store.resumeEvents(); tree.getView().refresh(); } else { tree.clearComponentFilter(); } }, clearComponentFilter: function() { var tree = this, store = tree.store, filtered = tree.filteredComponents || [], len = filtered.length, i = 0; for (; i < len; i++) { filtered[i].set('filtervisible', false); } store.clearFilter(); }, buildNode: function(comp) { var me = this, ownerCt = me.getRefOwner(), childItems = comp.items, viewModel = comp.viewModel, bindings = comp.bindings, hasBindings = !!comp.bindings, suffix = [], sansData = [], missing = {}, binding, len, i, o, child, ref, key, bindData; if (viewModel) { suffix.push('' + me.vmIcon + ''); ownerCt.buildVMDataMap(viewModel); } if (hasBindings) { suffix.push('' + me.bindingsIcon + ''); for (key in bindings) { binding = bindings[key]; if (binding.descriptor && Ext.isEmpty(binding.value)) { sansData.push(missing[key] = binding.descriptor); } } bindData = comp.bindData = Ext.app.bindinspector.Util.buildBindData(bindings); } if (sansData.length === 0) { sansData = undefined; } ref = comp.reference ? '[' + comp.reference + '] • ' : ''; o = { id: comp.id, text: ref + comp.id + (suffix.length ? (' ' + suffix.join(' ')) : ''), hasViewModel: !!viewModel, hasBindings: hasBindings, hasDeepBindings: hasBindings, reference: comp.reference, sansData: sansData, bindData: bindData, children: [] }; if (childItems) { for (i = 0 , len = childItems.length; i < len; ++i) { child = me.buildNode(childItems[i]); o.hasDeepBindings = o.hasDeepBindings || child.hasDeepBindings; if (child.hasDeepBindings) { o.children.push(child); } } } if (o.children.length) { o.expanded = true; o.leaf = false; } else { o.leaf = true; } return o; }, onItemDblclick: function(view, rec) { this.fireEvent('componentdblclick', this, rec); }, onItemSelect: function(selModel, rec) { var node = this.getView().getNode(rec); this.fireEvent('componentselect', this, rec, node); } }, function() { this.prototype.Model = Ext.define(null, { extend: 'Ext.data.TreeModel', fields: [ 'hasViewModel', 'hasBindings', 'reference', 'hasDeepBindings', 'reference', 'sansData', 'bindData', 'isSrcVM' ] }); }); Ext.define('Ext.resizer.BorderSplitter', { extend: 'Ext.resizer.Splitter', uses: [ 'Ext.resizer.BorderSplitterTracker' ], alias: 'widget.bordersplitter', collapseTarget: null, getTrackerConfig: function() { var trackerConfig = this.callParent(); trackerConfig.xclass = 'Ext.resizer.BorderSplitterTracker'; return trackerConfig; }, onTargetCollapse: function(target) { this.callParent([ target ]); if (this.performCollapse !== false && target.collapseMode == 'mini') { target.addCls(target.baseCls + '-' + target.collapsedCls + '-mini'); } }, onTargetExpand: function(target) { this.callParent([ target ]); if (this.performCollapse !== false && target.collapseMode == 'mini') { target.removeCls(target.baseCls + '-' + target.collapsedCls + '-mini'); } } }); Ext.define('Ext.layout.container.Border', { extend: 'Ext.layout.container.Container', alias: 'layout.border', alternateClassName: 'Ext.layout.BorderLayout', requires: [ 'Ext.resizer.BorderSplitter', 'Ext.fx.Anim', 'Ext.layout.container.border.Region' ], targetCls: Ext.baseCSSPrefix + 'border-layout-ct', itemCls: [ Ext.baseCSSPrefix + 'border-item', Ext.baseCSSPrefix + 'box-item' ], type: 'border', isBorderLayout: true, padding: undefined, percentageRe: /(\d+)%/, horzPositionProp: 'left', padOnContainerProp: 'left', padNotOnContainerProp: 'right', axisProps: { horz: { borderBegin: 'west', borderEnd: 'east', horizontal: true, posProp: 'x', sizeProp: 'width', sizePropCap: 'Width' }, vert: { borderBegin: 'north', borderEnd: 'south', horizontal: false, posProp: 'y', sizeProp: 'height', sizePropCap: 'Height' } }, centerRegion: null, manageMargins: true, panelCollapseAnimate: true, panelCollapseMode: 'placeholder', regionWeights: { north: 20, south: 10, center: 0, west: -10, east: -20 }, beginAxis: function(ownerContext, regions, name) { var me = this, props = me.axisProps[name], isVert = !props.horizontal, sizeProp = props.sizeProp, totalFlex = 0, childItems = ownerContext.childItems, length = childItems.length, center, i, childContext, centerFlex, comp, region, match, size, type, target, placeholder; for (i = 0; i < length; ++i) { childContext = childItems[i]; comp = childContext.target; childContext.layoutPos = {}; if (comp.region) { childContext.region = region = comp.region; childContext.isCenter = comp.isCenter; childContext.isHorz = comp.isHorz; childContext.isVert = comp.isVert; childContext.weight = comp.weight || me.regionWeights[region] || 0; comp.weight = childContext.weight; regions[comp.id] = childContext; if (comp.isCenter) { center = childContext; centerFlex = comp.flex; ownerContext.centerRegion = center; continue; } if (isVert !== childContext.isVert) { continue; } childContext.reverseWeighting = (region === props.borderEnd); size = comp[sizeProp]; type = typeof size; if (!comp.collapsed) { if (type === 'string' && (match = me.percentageRe.exec(size))) { childContext.percentage = parseInt(match[1], 10); } else if (comp.flex) { totalFlex += childContext.flex = comp.flex; } } } } if (center) { target = center.target; if ((placeholder = target.placeholderFor)) { if (!centerFlex && isVert === placeholder.collapsedVertical()) { centerFlex = 0; center.collapseAxis = name; } } else if (target.collapsed && (isVert === target.collapsedVertical())) { centerFlex = 0; center.collapseAxis = name; } } if (centerFlex == null) { centerFlex = 1; } totalFlex += centerFlex; return Ext.apply({ before: isVert ? 'top' : 'left', totalFlex: totalFlex }, props); }, beginLayout: function(ownerContext) { var me = this, items = me.getLayoutItems(), pad = me.padding, type = typeof pad, padOnContainer = false, childContext, item, length, i, regions, collapseTarget, doShow, hidden, region; if (ownerContext.heightModel.shrinkWrap) { Ext.Error.raise("Border layout does not currently support shrinkWrap height. " + "Please specify a height on component: " + me.owner.id + ", or use a container layout that sets the component's height."); } if (ownerContext.widthModel.shrinkWrap) { Ext.Error.raise("Border layout does not currently support shrinkWrap width. " + "Please specify a width on component: " + me.owner.id + ", or use a container layout that sets the component's width."); } if (pad) { if (type === 'string' || type === 'number') { pad = Ext.util.Format.parseBox(pad); } } else { pad = ownerContext.getEl('getTargetEl').getPaddingInfo(); padOnContainer = true; } ownerContext.outerPad = pad; ownerContext.padOnContainer = padOnContainer; for (i = 0 , length = items.length; i < length; ++i) { item = items[i]; collapseTarget = me.getSplitterTarget(item); if (collapseTarget) { doShow = undefined; hidden = !!item.hidden; if (!collapseTarget.split) { if (collapseTarget.isCollapsingOrExpanding) { doShow = !!collapseTarget.collapsed; } } else if (hidden !== collapseTarget.hidden) { doShow = !collapseTarget.hidden; } if (doShow) { item.show(); } else if (doShow === false) { item.hide(); } } } me.callParent(arguments); items = ownerContext.childItems; length = items.length; regions = {}; ownerContext.borderAxisHorz = me.beginAxis(ownerContext, regions, 'horz'); ownerContext.borderAxisVert = me.beginAxis(ownerContext, regions, 'vert'); for (i = 0; i < length; ++i) { childContext = items[i]; collapseTarget = me.getSplitterTarget(childContext.target); if (collapseTarget) { region = regions[collapseTarget.id]; if (!region) { region = ownerContext.getEl(collapseTarget.el, me); region.region = collapseTarget.region; } childContext.collapseTarget = collapseTarget = region; childContext.weight = collapseTarget.weight; childContext.reverseWeighting = collapseTarget.reverseWeighting; collapseTarget.splitter = childContext; childContext.isHorz = collapseTarget.isHorz; childContext.isVert = collapseTarget.isVert; } } me.sortWeightedItems(items, 'reverseWeighting'); me.setupSplitterNeighbors(items); }, calculate: function(ownerContext) { var me = this, containerSize = me.getContainerSize(ownerContext), childItems = ownerContext.childItems, length = childItems.length, horz = ownerContext.borderAxisHorz, vert = ownerContext.borderAxisVert, pad = ownerContext.outerPad, padOnContainer = ownerContext.padOnContainer, i, childContext, childMargins, size, horzPercentTotal, vertPercentTotal; horz.begin = pad[me.padOnContainerProp]; vert.begin = pad.top; horzPercentTotal = horz.end = horz.flexSpace = containerSize.width + (padOnContainer ? pad[me.padOnContainerProp] : -pad[me.padNotOnContainerProp]); vertPercentTotal = vert.end = vert.flexSpace = containerSize.height + (padOnContainer ? pad.top : -pad.bottom); for (i = 0; i < length; ++i) { childContext = childItems[i]; childMargins = childContext.getMarginInfo(); if (childContext.isHorz || childContext.isCenter) { horz.addUnflexed(childMargins.width); horzPercentTotal -= childMargins.width; } if (childContext.isVert || childContext.isCenter) { vert.addUnflexed(childMargins.height); vertPercentTotal -= childMargins.height; } if (!childContext.flex && !childContext.percentage) { if (childContext.isHorz || (childContext.isCenter && childContext.collapseAxis === 'horz')) { size = childContext.getProp('width'); horz.addUnflexed(size); if (childContext.collapseTarget) { horzPercentTotal -= size; } } else if (childContext.isVert || (childContext.isCenter && childContext.collapseAxis === 'vert')) { size = childContext.getProp('height'); vert.addUnflexed(size); if (childContext.collapseTarget) { vertPercentTotal -= size; } } } } for (i = 0; i < length; ++i) { childContext = childItems[i]; childMargins = childContext.getMarginInfo(); if (childContext.percentage) { if (childContext.isHorz) { size = Math.ceil(horzPercentTotal * childContext.percentage / 100); size = childContext.setWidth(size); horz.addUnflexed(size); } else if (childContext.isVert) { size = Math.ceil(vertPercentTotal * childContext.percentage / 100); size = childContext.setHeight(size); vert.addUnflexed(size); } } } for (i = 0; i < length; ++i) { childContext = childItems[i]; if (!childContext.isCenter) { me.calculateChildAxis(childContext, horz); me.calculateChildAxis(childContext, vert); } } if (me.finishAxis(ownerContext, vert) + me.finishAxis(ownerContext, horz) < 2) { me.done = false; } else { me.finishPositions(childItems); } }, calculateChildAxis: function(childContext, axis) { var collapseTarget = childContext.collapseTarget, setSizeMethod = 'set' + axis.sizePropCap, sizeProp = axis.sizeProp, childMarginSize = childContext.getMarginInfo()[sizeProp], region, isBegin, flex, pos, size; if (collapseTarget) { region = collapseTarget.region; } else { region = childContext.region; flex = childContext.flex; } isBegin = region === axis.borderBegin; if (!isBegin && region !== axis.borderEnd) { childContext[setSizeMethod](axis.end - axis.begin - childMarginSize); pos = axis.begin; } else { if (flex) { size = Math.ceil(axis.flexSpace * (flex / axis.totalFlex)); size = childContext[setSizeMethod](size); } else if (childContext.percentage) { size = childContext.peek(sizeProp); } else { size = childContext.getProp(sizeProp); } size += childMarginSize; if (isBegin) { pos = axis.begin; axis.begin += size; } else { axis.end = pos = axis.end - size; } } childContext.layoutPos[axis.posProp] = pos; }, eachItem: function(region, fn, scope) { var me = this, items = me.getLayoutItems(), i = 0, item; if (Ext.isFunction(region)) { fn = region; scope = fn; } for (i; i < items.length; i++) { item = items[i]; if (!region || item.region === region) { if (fn.call(scope, item) === false) { break; } } } }, finishAxis: function(ownerContext, axis) { var size = axis.end - axis.begin, center = ownerContext.centerRegion; if (center) { center['set' + axis.sizePropCap](size - center.getMarginInfo()[axis.sizeProp]); center.layoutPos[axis.posProp] = axis.begin; } return Ext.isNumber(size) ? 1 : 0; }, finishPositions: function(childItems) { var length = childItems.length, index, childContext, marginProp = this.horzPositionProp; for (index = 0; index < length; ++index) { childContext = childItems[index]; childContext.setProp('x', childContext.layoutPos.x + childContext.marginInfo[marginProp]); childContext.setProp('y', childContext.layoutPos.y + childContext.marginInfo.top); } }, getLayoutItems: function() { var owner = this.owner, ownerItems = (owner && owner.items && owner.items.items) || [], length = ownerItems.length, items = [], i = 0, ownerItem, placeholderFor; for (; i < length; i++) { ownerItem = ownerItems[i]; placeholderFor = ownerItem.placeholderFor; if (ownerItem.hidden || ((!ownerItem.floated || ownerItem.isCollapsingOrExpanding === 2) && !(placeholderFor && placeholderFor.isCollapsingOrExpanding === 2))) { items.push(ownerItem); } } return items; }, getPlaceholder: function(comp) { return comp.getPlaceholder && comp.getPlaceholder(); }, getMaxWeight: function(region) { return this.getMinMaxWeight(region); }, getMinWeight: function(region) { return this.getMinMaxWeight(region, true); }, getMinMaxWeight: function(region, min) { var me = this, weight = null; me.eachItem(region, function(item) { if (item.hasOwnProperty('weight')) { if (weight === null) { weight = item.weight; return; } if ((min && item.weight < weight) || item.weight > weight) { weight = item.weight; } } }, this); return weight; }, getSplitterTarget: function(splitter) { var collapseTarget = splitter.collapseTarget; if (collapseTarget && collapseTarget.collapsed) { return collapseTarget.placeholder || collapseTarget; } return collapseTarget; }, isItemBoxParent: function(itemContext) { return true; }, isItemShrinkWrap: function(item) { return true; }, insertSplitter: function(item, index, hidden, splitterCfg) { var region = item.region, splitter = Ext.apply({ xtype: 'bordersplitter', collapseTarget: item, id: item.id + '-splitter', hidden: hidden, canResize: item.splitterResize !== false, splitterFor: item, synthetic: true }, splitterCfg), at = index + ((region === 'south' || region === 'east') ? 0 : 1); if (item.collapseMode === 'mini') { splitter.collapsedCls = item.collapsedCls; } item.splitter = this.owner.add(at, splitter); }, getMoveAfterIndex: function(after) { var index = this.callParent(arguments); if (after.splitter) { index++; } return index; }, moveItemBefore: function(item, before) { var beforeRegion; if (before && before.splitter) { beforeRegion = before.region; if (beforeRegion === 'south' || beforeRegion === 'east') { before = before.splitter; } } return this.callParent([ item, before ]); }, onAdd: function(item, index) { var me = this, placeholderFor = item.placeholderFor, region = item.region, isCenter, split, hidden, cfg; me.callParent(arguments); if (region) { Ext.apply(item, me.regionFlags[region]); if (item.initBorderRegion) { item.initBorderRegion(); } isCenter = region === 'center'; if (isCenter) { if (me.centerRegion) { Ext.Error.raise("Cannot have multiple center regions in a BorderLayout."); } me.centerRegion = item; } else { split = item.split; hidden = !!item.hidden; if (typeof split === 'object') { cfg = split; split = true; } if ((item.isHorz || item.isVert) && (split || item.collapseMode === 'mini')) { me.insertSplitter(item, index, hidden || !split, cfg); } } if (!isCenter && !item.hasOwnProperty('collapseMode')) { item.collapseMode = me.panelCollapseMode; } if (!item.hasOwnProperty('animCollapse')) { if (item.collapseMode !== 'placeholder') { item.animCollapse = false; } else { item.animCollapse = me.panelCollapseAnimate; } } } else if (placeholderFor) { Ext.apply(item, me.regionFlags[placeholderFor.region]); item.region = placeholderFor.region; item.weight = placeholderFor.weight; } }, onDestroy: function() { this.centerRegion = null; this.callParent(); }, onRemove: function(comp, isDestroying) { var me = this, region = comp.region, splitter = comp.splitter, owner = me.owner, destroying = owner.destroying, el; if (region) { if (comp.isCenter) { me.centerRegion = null; } delete comp.isCenter; delete comp.isHorz; delete comp.isVert; if (splitter && !owner.destroying) { owner.doRemove(splitter, true); } delete comp.splitter; } me.callParent(arguments); if (!destroying && !isDestroying && comp.rendered) { el = comp.getEl(); if (el) { el.setStyle('top', ''); el.setStyle(me.horzPositionProp, ''); } } }, regionMeta: { center: { splitterDelta: 0 }, north: { splitterDelta: 1 }, south: { splitterDelta: -1 }, west: { splitterDelta: 1 }, east: { splitterDelta: -1 } }, regionFlags: { center: { isCenter: true, isHorz: false, isVert: false }, north: { isCenter: false, isHorz: false, isVert: true, collapseDirection: 'top' }, south: { isCenter: false, isHorz: false, isVert: true, collapseDirection: 'bottom' }, west: { isCenter: false, isHorz: true, isVert: false, collapseDirection: 'left' }, east: { isCenter: false, isHorz: true, isVert: false, collapseDirection: 'right' } }, setupSplitterNeighbors: function(items) { var edgeRegions = {}, length = items.length, touchedRegions = this.touchedRegions, i, j, center, count, edge, comp, region, splitter, touched; for (i = 0; i < length; ++i) { comp = items[i].target; region = comp.region; if (comp.isCenter) { center = comp; } else if (region) { touched = touchedRegions[region]; for (j = 0 , count = touched.length; j < count; ++j) { edge = edgeRegions[touched[j]]; if (edge) { edge.neighbors.push(comp); } } if (comp.placeholderFor) { splitter = comp.placeholderFor.splitter; } else { splitter = comp.splitter; } if (splitter) { splitter.neighbors = []; } edgeRegions[region] = splitter; } } if (center) { touched = touchedRegions.center; for (j = 0 , count = touched.length; j < count; ++j) { edge = edgeRegions[touched[j]]; if (edge) { edge.neighbors.push(center); } } } }, touchedRegions: { center: [ 'north', 'south', 'east', 'west' ], north: [ 'north', 'east', 'west' ], south: [ 'south', 'east', 'west' ], east: [ 'east', 'north', 'south' ], west: [ 'west', 'north', 'south' ] }, sizePolicies: { vert: { readsWidth: 0, readsHeight: 1, setsWidth: 1, setsHeight: 0 }, horz: { readsWidth: 1, readsHeight: 0, setsWidth: 0, setsHeight: 1 }, flexAll: { readsWidth: 0, readsHeight: 0, setsWidth: 1, setsHeight: 1 } }, getItemSizePolicy: function(item) { var me = this, policies = this.sizePolicies, collapseTarget, size, policy, placeholderFor; if (item.isCenter) { placeholderFor = item.placeholderFor; if (placeholderFor) { if (placeholderFor.collapsedVertical()) { return policies.vert; } return policies.horz; } if (item.collapsed) { if (item.collapsedVertical()) { return policies.vert; } return policies.horz; } return policies.flexAll; } collapseTarget = item.collapseTarget; if (collapseTarget) { return collapseTarget.isVert ? policies.vert : policies.horz; } if (item.region) { if (item.isVert) { size = item.height; policy = policies.vert; } else { size = item.width; policy = policies.horz; } if (item.flex || (typeof size === 'string' && me.percentageRe.test(size))) { return policies.flexAll; } return policy; } return me.autoSizePolicy; } }, function() { var methods = { addUnflexed: function(px) { this.flexSpace = Math.max(this.flexSpace - px, 0); } }, props = this.prototype.axisProps; Ext.apply(props.horz, methods); Ext.apply(props.vert, methods); }); Ext.define('Ext.layout.container.Card', { extend: 'Ext.layout.container.Fit', alternateClassName: 'Ext.layout.CardLayout', alias: 'layout.card', type: 'card', hideInactive: true, deferredRender: false, scrollableCache: (Ext.isGecko ? {} : null), getRenderTree: function() { var me = this, activeItem = me.getActiveItem(); if (activeItem) { if (activeItem.hasListeners.beforeactivate && activeItem.fireEvent('beforeactivate', activeItem) === false) { activeItem = me.activeItem = me.owner.activeItem = null; } else if (activeItem.hasListeners.activate) { activeItem.on({ boxready: function() { activeItem.fireEvent('activate', activeItem); }, single: true }); } if (me.deferredRender) { if (activeItem) { return me.getItemsRenderTree([ activeItem ]); } } else { return me.callParent(arguments); } } }, renderChildren: function() { var me = this, active = me.getActiveItem(); if (!me.deferredRender) { me.callParent(); } else if (active) { me.renderItems([ active ], me.getRenderTarget()); } }, isValidParent: function(item, target, position) { var itemEl = item.el ? item.el.dom : Ext.getDom(item); return (itemEl && itemEl.parentNode === (target.dom || target)) || false; }, getActiveItem: function() { var me = this, item = me.activeItem === undefined ? (me.owner && me.owner.activeItem) : me.activeItem, result = me.parseActiveItem(item); if (result && me.owner.items.indexOf(result) !== -1) { me.activeItem = result; } return result == null ? null : (me.activeItem || me.owner.activeItem); }, parseActiveItem: function(item) { var activeItem; if (item && item.isComponent) { activeItem = item; } else if (typeof item === 'number' || item === undefined) { activeItem = this.getLayoutItems()[item || 0]; } else if (item === null) { activeItem = null; } else { activeItem = this.owner.getComponent(item); } return activeItem; }, configureItem: function(item) { item.setHiddenState(item !== this.getActiveItem()); this.callParent(arguments); }, onRemove: function(component) { this.callParent([ component ]); if (component === this.activeItem) { this.activeItem = undefined; } }, getAnimation: function(newCard, owner) { var newAnim = (newCard || {}).cardSwitchAnimation; if (newAnim === false) { return false; } return newAnim || owner.cardSwitchAnimation; }, getNext: function() { var wrap = arguments[0], items = this.getLayoutItems(), index = Ext.Array.indexOf(items, this.activeItem); return items[index + 1] || (wrap ? items[0] : false); }, next: function() { var anim = arguments[0], wrap = arguments[1]; return this.setActiveItem(this.getNext(wrap), anim); }, getPrev: function() { var wrap = arguments[0], items = this.getLayoutItems(), index = Ext.Array.indexOf(items, this.activeItem); return items[index - 1] || (wrap ? items[items.length - 1] : false); }, prev: function() { var anim = arguments[0], wrap = arguments[1]; return this.setActiveItem(this.getPrev(wrap), anim); }, setActiveItem: function(newCard) { var me = this, scrollableCache = me.scrollableCache, owner = me.owner, oldCard = me.activeItem, rendered = owner.rendered, newIndex, focusNewCard, oldCardScrollable, cached, currentPosition; newCard = me.parseActiveItem(newCard); newIndex = owner.items.indexOf(newCard); if (newIndex === -1) { newIndex = owner.items.items.length; Ext.suspendLayouts(); newCard = owner.add(newCard); Ext.resumeLayouts(); } if (newCard && oldCard !== newCard) { if (newCard.fireEvent('beforeactivate', newCard, oldCard) === false) { return false; } if (oldCard && oldCard.fireEvent('beforedeactivate', oldCard, newCard) === false) { return false; } if (rendered) { Ext.suspendLayouts(); if (!newCard.rendered) { me.renderItem(newCard, me.getRenderTarget(), owner.items.length); } if (oldCard) { if (me.hideInactive) { focusNewCard = oldCard.el.contains(Ext.Element.getActiveElement()); if (scrollableCache && (oldCardScrollable = oldCard.scrollable)) { scrollableCache[oldCard.id] = { position: oldCardScrollable.getPosition() }; oldCardScrollable.scrollTo(0, 0); } oldCard.hide(); if (oldCard.hidden) { oldCard.hiddenByLayout = true; oldCard.fireEvent('deactivate', oldCard, newCard); } else { return false; } } } if (newCard.hidden) { newCard.show(); } if (newCard.hidden) { me.activeItem = newCard = null; } else { me.activeItem = newCard; if (focusNewCard) { if (!newCard.defaultFocus) { newCard.defaultFocus = ':focusable'; } newCard.focus(); } } Ext.resumeLayouts(true); if (scrollableCache && (cached = scrollableCache[newCard.id])) { currentPosition = cached.position; newCard.scrollable.scrollTo(currentPosition.x, currentPosition.y); } } else { me.activeItem = newCard; } newCard.fireEvent('activate', newCard, oldCard); return me.activeItem; } return false; } }); Ext.define('Ext.dom.ButtonElement', { extend: 'Ext.dom.Element', setSize: function(width, height, animate) { var me = this, component = me.component; me.callParent([ width, height, animate ]); component.btnWrap.setStyle('table-layout', (!width || width === 'auto') ? '' : 'fixed'); component.btnEl.setStyle('height', (!height || height === 'auto') ? '' : 'auto'); return me; }, setStyle: function(prop, value) { var me = this, component = me.component, width, height; me.callParent([ prop, value ]); if (prop) { if (prop === 'width' || (typeof prop !== 'string' && 'width' in prop)) { width = value || prop.width; component.btnWrap.setStyle('table-layout', (!width || width === 'auto') ? '' : 'fixed'); } if (prop === 'height' || (typeof prop !== 'string' && 'height' in prop)) { height = value || prop.height; component.btnEl.setStyle('height', (!height || height === 'auto') ? '' : 'auto'); } } return me; }, setHeight: function(height, animate) { this.callParent([ height, animate ]); this.component.btnEl.setStyle('height', (!height || height === 'auto') ? '' : 'auto'); return this; }, setWidth: function(width, animate) { this.callParent([ width, animate ]); this.component.btnWrap.setStyle('table-layout', (!width || width === 'auto') ? '' : 'fixed'); return this; } }); Ext.define('Ext.button.Manager', { singleton: true, alternateClassName: 'Ext.ButtonToggleManager', groups: {}, pressedButton: null, buttonSelector: '.' + Ext.baseCSSPrefix + 'btn', init: function() { var me = this; if (!me.initialized) { Ext.getDoc().on({ keydown: me.onDocumentKeyDown, mouseup: me.onDocumentMouseUp, scope: me }); me.initialized = true; } }, onDocumentKeyDown: function(e) { var k = e.getKey(), btn; if (k === e.SPACE || k === e.ENTER) { btn = e.getTarget(this.buttonSelector); if (btn) { Ext.getCmp(btn.id).onClick(e); } } }, onButtonMousedown: function(button, e) { var pressed = this.pressedButton; if (pressed) { pressed.onMouseUp(e); } this.pressedButton = button; }, onDocumentMouseUp: function(e) { var pressed = this.pressedButton; if (pressed) { pressed.onMouseUp(e); this.pressedButton = null; } }, toggleGroup: function(btn, state) { if (state) { var g = this.groups[btn.toggleGroup], length = g.length, i; for (i = 0; i < length; i++) { if (g[i] !== btn) { g[i].toggle(false); } } } }, register: function(btn) { var me = this, groups = this.groups, group = groups[btn.toggleGroup]; me.init(); if (!btn.toggleGroup) { return; } if (!group) { group = groups[btn.toggleGroup] = []; } group.push(btn); btn.on('toggle', me.toggleGroup, me); }, unregister: function(btn) { if (!btn.toggleGroup) { return; } var me = this, group = me.groups[btn.toggleGroup]; if (group) { Ext.Array.remove(group, btn); btn.un('toggle', me.toggleGroup, me); } }, getPressed: function(groupName) { var group = this.groups[groupName], i = 0, len; if (group) { for (len = group.length; i < len; i++) { if (group[i].pressed === true) { return group[i]; } } } return null; } }); Ext.define('Ext.menu.Manager', { singleton: true, alternateClassName: 'Ext.menu.MenuMgr', uses: [ 'Ext.menu.Menu' ], groups: {}, visible: [], constructor: function() { var me = this; me.onShow = function() { delete me.onShow; Ext.on('mousedown', me.checkActiveMenus, me); return me.onShow.apply(me, arguments); }; }, checkActiveMenus: function(e) { var allMenus = this.visible, len = allMenus.length, i, menu; if (len) { allMenus = allMenus.slice(); for (i = 0; i < len; ++i) { menu = allMenus[i]; if (!menu.owns(e)) { menu.hide(); } } } }, onShow: function(menu) { if (menu.floating) { Ext.Array.include(this.visible, menu); } }, onHide: function(menu) { if (menu.floating) { Ext.Array.remove(this.visible, menu); } }, hideAll: function() { var allMenus = this.visible, len = allMenus.length, result = false, i; if (len) { allMenus = allMenus.slice(); for (i = 0; i < len; i++) { allMenus[i].hide(); result = true; } } return result; }, get: function(menu, config) { var result; if (typeof menu === 'string') { result = Ext.getCmp(menu); if (result instanceof Ext.menu.Menu) { menu = result; } } else if (Ext.isArray(menu)) { config = Ext.apply({ items: menu }, config); menu = new Ext.menu.Menu(config); } else if (!menu.isComponent) { config = Ext.apply({}, menu, config); menu = Ext.ComponentManager.create(config, 'menu'); } return menu; }, 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.dom.ButtonElement', 'Ext.button.Manager', 'Ext.menu.Manager', 'Ext.util.ClickRepeater', 'Ext.util.TextMetrics', 'Ext.util.KeyMap' ], mixins: [ 'Ext.mixin.Queryable' ], alternateClassName: 'Ext.Button', config: { iconAlign: 'left', text: null, textAlign: 'center', arrowVisible: true }, isButton: true, _syncFrameHeight: true, liquidLayout: true, hidden: false, disabled: false, pressed: false, tabIndex: 0, enableToggle: false, menuAlign: 'tl-bl?', showEmptyMenu: false, clickEvent: 'click', preventDefault: true, handleMouseEvents: true, tooltipType: 'qtip', baseCls: Ext.baseCSSPrefix + 'btn', hrefTarget: '_blank', destroyMenu: true, focusable: true, ariaRole: 'button', defaultBindProperty: 'text', childEls: [ 'btnEl', 'btnWrap', 'btnInnerEl', 'btnIconEl' ], publishes: { pressed: 1 }, _btnWrapCls: Ext.baseCSSPrefix + 'btn-wrap', _btnCls: Ext.baseCSSPrefix + 'btn-button', _baseIconCls: Ext.baseCSSPrefix + 'btn-icon-el', _glyphCls: Ext.baseCSSPrefix + 'btn-glyph', _innerCls: Ext.baseCSSPrefix + 'btn-inner', _textCls: Ext.baseCSSPrefix + 'btn-text', _noTextCls: Ext.baseCSSPrefix + 'btn-no-text', _hasIconCls: Ext.baseCSSPrefix + 'btn-icon', _pressedCls: Ext.baseCSSPrefix + 'btn-pressed', overCls: Ext.baseCSSPrefix + 'btn-over', _disabledCls: Ext.baseCSSPrefix + 'btn-disabled', _menuActiveCls: Ext.baseCSSPrefix + 'btn-menu-active', _operaArrowCls: Ext.baseCSSPrefix + 'opera12m-btn-arrow', renderTpl: '' + '' + '{[values.$comp.renderIcon(values)]}' + '{text}' + '{[values.$comp.renderIcon(values)]}' + '' + '' + '{[values.$comp.getAfterMarkup ? values.$comp.getAfterMarkup(values) : ""]}' + '' + '' + '' + ' {closeText}' + '' + '' + '', iconTpl: 'background-image:url({iconUrl});
' + 'font-family:{glyphFontFamily};">' + '&#{glyph}; ' + '', scale: 'small', allowedScales: [ 'small', 'medium', 'large' ], arrowAlign: 'right', arrowCls: 'arrow', maskOnDisable: false, shrinkWrap: 3, frame: true, autoEl: { tag: 'a', hidefocus: 'on', unselectable: 'on' }, hasFrameTable: function() { return this.href && this.frameTable; }, frameTableListener: function() { if (!this.disabled) { this.doNavigate(); } }, doNavigate: function() { if (this.hrefTarget === '_blank') { window.open(this.getHref(), this.hrefTarget); } else { location.href = this.getHref(); } }, _triggerRegion: {}, initComponent: function() { var me = this; me.addCls(Ext.baseCSSPrefix + 'unselectable'); if (Ext.isOpera12m && (me.split || me.menu) && me.getArrowVisible()) { me.addCls(me._operaArrowCls + '-' + me.arrowAlign); } me.callParent(); if (me.menu) { me.split = true; me.setMenu(me.menu, false, true); } if (me.url) { me.href = me.url; } me.configuredWithPreventDefault = me.hasOwnProperty('preventDefault'); if (me.href && !me.configuredWithPreventDefault) { me.preventDefault = false; } if (Ext.isString(me.toggleGroup) && me.toggleGroup !== '') { me.enableToggle = true; } if (me.html && !me.text) { me.text = me.html; delete me.html; } }, getElConfig: function() { var me = this, config = me.callParent(), href = me.getHref(), hrefTarget = me.hrefTarget; if (config.tag === 'a') { if (!me.disabled) { config.tabIndex = me.tabIndex; } if (href) { if (!me.disabled) { config.href = href; if (hrefTarget) { config.target = hrefTarget; } } } } return config; }, beforeRender: function() { this.callParent(); if (this.pressed) { this.addCls(this._pressedCls); } }, initRenderData: function() { return Ext.apply(this.callParent(), this.getTemplateArgs()); }, getMenu: function() { return this.menu || null; }, setMenu: function(menu, destroyMenu, initial) { var me = this, oldMenu = me.menu, instanced; if (oldMenu && !initial) { if (destroyMenu !== false && me.destroyMenu) { oldMenu.destroy(); } oldMenu.ownerCmp = null; } if (menu) { instanced = menu.isMenu; menu = Ext.menu.Manager.get(menu, { ownerCmp: me }); menu.setOwnerCmp(me, instanced); menu.menuClickBuffer = 250; me.mon(menu, { scope: me, show: me.onMenuShow, hide: me.onMenuHide }); if (!oldMenu && me.getArrowVisible()) { me.split = true; if (me.rendered) { me._addSplitCls(); me.updateLayout(); } } me.menu = menu; } else { if (me.rendered) { me._removeSplitCls(); me.updateLayout(); } me.split = false; me.menu = null; } }, onRender: function() { var me = this, addOnclick, btn, btnListeners; me.callParent(arguments); btn = me.el; if (me.tooltip) { me.setTooltip(me.tooltip, true); } if (me.handleMouseEvents) { btnListeners = { scope: me, mouseover: me.onMouseOver, mouseout: me.onMouseOut, mousedown: me.onMouseDown }; if (me.split) { btnListeners.mousemove = me.onMouseMove; } } else { btnListeners = { scope: me }; } if (Ext.supports.Touch) { btnListeners.touchstart = me.onTouchStart; } if (me.menu) { me.keyMap = new Ext.util.KeyMap({ target: me.el, key: Ext.event.Event.prototype.DOWN, handler: me.onDownKey, scope: me }); } if (me.repeat) { me.mon(new Ext.util.ClickRepeater(btn, Ext.isObject(me.repeat) ? me.repeat : {}), 'click', me.onRepeatClick, me); } else { if (btnListeners[me.clickEvent]) { addOnclick = true; } else { btnListeners[me.clickEvent] = me.onClick; } } me.mon(btn, btnListeners); if (me.hasFrameTable()) { me.mon(me.frameTable, 'click', me.frameTableListener, me); } if (addOnclick) { me.mon(btn, me.clickEvent, me.onClick, me); } Ext.button.Manager.register(me); }, onFocusLeave: function(e) { this.callParent([ e ]); if (this.menu) { this.menu.hide(); } }, getTemplateArgs: function() { var me = this, btnCls = me._btnCls, baseIconCls = me._baseIconCls, iconAlign = me.getIconAlign(), glyph = me.glyph, glyphFontFamily = Ext._glyphFontFamily, text = me.text, hasIcon = me._hasIcon(), hasIconCls = me._hasIconCls, glyphParts; if (typeof glyph === 'string') { glyphParts = glyph.split('@'); glyph = glyphParts[0]; glyphFontFamily = glyphParts[1]; } return { innerCls: me._innerCls, splitCls: me.getArrowVisible() ? me.getSplitCls() : '', iconUrl: me.icon, iconCls: me.iconCls, glyph: glyph, glyphCls: glyph ? me._glyphCls : '', glyphFontFamily: glyphFontFamily, text: text || ' ', closeText: me.closeText, textCls: text ? me._textCls : '', noTextCls: text ? '' : me._noTextCls, hasIconCls: hasIcon ? hasIconCls : '', btnWrapCls: me._btnWrapCls, btnWrapStyle: me.width ? 'table-layout:fixed;' : '', btnElStyle: me.height ? 'height:auto;' : '', btnCls: btnCls, baseIconCls: baseIconCls, iconBeforeText: iconAlign === 'left' || iconAlign === 'top', iconAlignCls: hasIcon ? (hasIconCls + '-' + iconAlign) : '', textAlignCls: btnCls + '-' + me.getTextAlign() }; }, renderIcon: function(values) { return this.getTpl('iconTpl').apply(values); }, setHref: function(href) { var me = this, hrefTarget = me.hrefTarget, dom; me.href = href; if (!me.configuredWithPreventDefault) { me.preventDefault = !href; } if (me.rendered) { dom = me.el.dom; if (!href || me.disabled) { dom.removeAttribute('href'); dom.removeAttribute('hrefTarget'); } else { dom.href = me.getHref(); if (hrefTarget) { dom.target = hrefTarget; } } } }, getHref: function() { var me = this, href = me.href; return href ? Ext.urlAppend(href, Ext.Object.toQueryString(Ext.apply({}, me.params, me.baseParams))) : false; }, setParams: function(params) { var me = this, dom; me.params = params; if (me.rendered) { dom = me.el.dom; if (me.disabled) { dom.removeAttribute('href'); } else { dom.href = me.getHref() || ''; } } }, getSplitCls: function() { var me = this; return me.split ? (me.baseCls + '-' + me.arrowCls) + ' ' + (me.baseCls + '-' + me.arrowCls + '-' + me.arrowAlign) : ''; }, setIcon: function(icon) { icon = icon || ''; var me = this, btnIconEl = me.btnIconEl, oldIcon = me.icon || ''; me.icon = icon; if (icon !== oldIcon) { if (btnIconEl) { btnIconEl.setStyle('background-image', icon ? 'url(' + icon + ')' : ''); me._syncHasIconCls(); if (me.didIconStateChange(oldIcon, icon)) { me.updateLayout(); } } me.fireEvent('iconchange', me, oldIcon, icon); } return me; }, setIconCls: function(cls) { cls = cls || ''; var me = this, btnIconEl = me.btnIconEl, oldCls = me.iconCls || ''; me.iconCls = cls; if (oldCls !== cls) { if (btnIconEl) { btnIconEl.removeCls(oldCls); btnIconEl.addCls(cls); me._syncHasIconCls(); if (me.didIconStateChange(oldCls, cls)) { me.updateLayout(); } } me.fireEvent('iconchange', me, oldCls, cls); } return me; }, setGlyph: function(glyph) { glyph = glyph || 0; var me = this, btnIconEl = me.btnIconEl, oldGlyph = me.glyph, glyphCls = me._glyphCls, fontFamily, glyphParts; me.glyph = glyph; if (btnIconEl) { if (typeof glyph === 'string') { glyphParts = glyph.split('@'); glyph = glyphParts[0]; fontFamily = glyphParts[1] || Ext._glyphFontFamily; } if (!glyph) { btnIconEl.dom.innerHTML = ''; btnIconEl.removeCls(glyphCls); } else if (oldGlyph !== glyph) { btnIconEl.dom.innerHTML = '&#' + glyph + ';'; btnIconEl.addCls(glyphCls); } if (fontFamily) { btnIconEl.setStyle('font-family', fontFamily); } me._syncHasIconCls(); if (me.didIconStateChange(oldGlyph, glyph)) { me.updateLayout(); } } me.fireEvent('glyphchange', me, me.glyph, oldGlyph); return me; }, setTooltip: function(tooltip, initial) { var me = this; if (me.rendered) { if (!initial || !tooltip) { me.clearTip(); } if (tooltip) { if (Ext.quickTipsActive && Ext.isObject(tooltip)) { Ext.tip.QuickTipManager.register(Ext.apply({ target: me.el.id }, tooltip)); me.tooltip = tooltip; } else { me.el.dom.setAttribute(me.getTipAttr(), tooltip); } } } else { me.tooltip = tooltip; } return me; }, updateIconAlign: function(align, oldAlign) { var me = this, btnEl, btnIconEl, hasIconCls; if (me.rendered) { btnEl = me.btnEl; btnIconEl = me.btnIconEl; hasIconCls = me._hasIconCls; if (oldAlign) { btnEl.removeCls(hasIconCls + '-' + oldAlign); } btnEl.addCls(hasIconCls + '-' + align); if (align === 'top' || align === 'left') { btnEl.insertFirst(btnIconEl); } else { btnEl.appendChild(btnIconEl); } me.updateLayout(); } }, updateTextAlign: function(align, oldAlign) { var me = this, btnEl = me.btnEl, btnCls = me._btnCls; if (me.rendered) { btnEl.removeCls(btnCls + '-' + oldAlign); btnEl.addCls(btnCls + '-' + align); } }, getTipAttr: function() { return this.tooltipType === 'qtip' ? 'data-qtip' : 'title'; }, getRefItems: function(deep) { var menu = this.menu, items; if (menu) { items = menu.getRefItems(deep); items.unshift(menu); } return items || []; }, clearTip: function() { var me = this, el = me.el; if (Ext.quickTipsActive && Ext.isObject(me.tooltip)) { Ext.tip.QuickTipManager.unregister(el); } else { el.dom.removeAttribute(me.getTipAttr()); } }, beforeDestroy: function() { var me = this; if (me.rendered) { me.clearTip(); } Ext.destroy(me.repeater); me.callParent(); }, onDestroy: function() { var me = this, menu = me.menu; if (me.rendered) { Ext.destroy(me.keyMap); delete me.keyMap; } if (menu && me.destroyMenu) { me.menu = Ext.destroy(menu); } Ext.button.Manager.unregister(me); me.callParent(); }, setHandler: function(handler, scope) { this.handler = handler; if (arguments.length > 1) { this.scope = scope; } return this; }, updateText: function(text, oldText) { text = text == null ? '' : String(text); oldText = oldText || ''; var me = this, btnInnerEl = me.btnInnerEl, btnEl = me.btnEl; if (me.rendered) { btnInnerEl.setHtml(text || ' '); btnEl[text ? 'addCls' : 'removeCls'](me._textCls); btnEl[text ? 'removeCls' : 'addCls'](me._noTextCls); me.updateLayout(); } me.fireEvent('textchange', me, oldText, text); }, didIconStateChange: function(old, current) { var currentEmpty = Ext.isEmpty(current); return Ext.isEmpty(old) ? !currentEmpty : currentEmpty; }, setPressed: function(pressed) { return this.toggle(pressed !== false); }, toggle: function(state, suppressEvent) { var me = this; state = state === undefined ? !me.pressed : !!state; if (state !== me.pressed) { me[state ? 'addCls' : 'removeCls'](me._pressedCls); me.pressed = state; if (!suppressEvent) { me.fireEvent('toggle', me, state); Ext.callback(me.toggleHandler, me.scope, [ me, state ], 0, me); if (me.reference && me.publishState) { me.publishState('pressed', state); } } } return me; }, maybeShowMenu: function(e) { if (this.menu) { this.showMenu(e); } }, showMenu: function( clickEvent) { var me = this, menu = me.menu, isPointerEvent = !clickEvent || clickEvent.pointerType; if (menu && me.rendered) { if (me.tooltip && Ext.quickTipsActive && me.getTipAttr() !== 'title') { Ext.tip.QuickTipManager.getQuickTip().cancelShow(me.el); } if (menu.isVisible()) { if (isPointerEvent) { menu.hide(); } else { menu.focus(); } } else if (!clickEvent || me.showEmptyMenu || menu.items.getCount() > 0) { menu.autoFocus = !isPointerEvent; 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); }, onTouchStart: function(e) { this.doPreventDefault(e); }, onClick: function(e) { var me = this; me.doPreventDefault(e); if (e.type !== 'keydown' && e.button) { return; } if (!me.disabled) { me.doToggle(); me.maybeShowMenu(e); me.fireHandler(e); } }, doPreventDefault: function(e) { if (e && (this.preventDefault || (this.disabled && this.getHref()))) { e.preventDefault(); } }, fireHandler: function(e) { var me = this; if (me.fireEvent('click', me, e) !== false && !me.isDestroyed) { Ext.callback(me.handler, me.scope, [ me, e ], 0, me); } }, doToggle: function() { var me = this; if (me.enableToggle && (me.allowDepress !== false || !me.pressed)) { me.toggle(); } }, 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, over = me.overMenuTrigger; if (me.split) { if (me.isWithinTrigger(e)) { if (!over) { me.onMenuTriggerOver(e); } } else if (over) { me.onMenuTriggerOut(e); } } }, isWithinTrigger: function(e) { var me = this, el = me.el, overPosition, triggerRegion; overPosition = (me.arrowAlign === 'right') ? e.getX() - me.getX() : e.getY() - el.getY(); triggerRegion = me.getTriggerRegion(); return overPosition > triggerRegion.begin && overPosition < triggerRegion.end; }, getTriggerRegion: function() { var me = this, region = me._triggerRegion, isRight = me.arrowAlign === 'right', getEnd = isRight ? 'getRight' : 'getBottom', btnSize = isRight ? me.getWidth() : me.getHeight(); region.begin = btnSize - (me.el[getEnd]() - me.btnEl[getEnd]()); region.end = btnSize; return region; }, onMouseEnter: function(e) { this.fireEvent('mouseover', this, e); }, onMouseLeave: function(e) { this.fireEvent('mouseout', this, e); }, onMenuTriggerOver: function(e) { var me = this, arrowTip = me.arrowTooltip; me.overMenuTrigger = true; if (me.split && arrowTip) { me.btnWrap.dom.setAttribute(me.getTipAttr(), arrowTip); } me.fireEvent('menutriggerover', me, me.menu, e); }, onMenuTriggerOut: function(e) { var me = this; delete me.overMenuTrigger; if (me.split && me.arrowTooltip) { me.btnWrap.dom.setAttribute(me.getTipAttr(), ''); } me.fireEvent('menutriggerout', me, me.menu, e); }, enable: function(silent) { var me = this, href = me.href, hrefTarget = me.hrefTarget, dom; me.callParent(arguments); me.removeCls(me._disabledCls); if (me.rendered) { dom = me.el.dom; dom.setAttribute('tabindex', me.tabIndex); if (href) { dom.href = href; } if (hrefTarget) { dom.target = hrefTarget; } } return me; }, disable: function(silent) { var me = this, dom; me.callParent(arguments); me.addCls(me._disabledCls); me.removeCls(me.overCls); if (me.rendered) { dom = me.el.dom; dom.removeAttribute('tabindex'); if (me.href) { dom.removeAttribute('href'); } if (me.hrefTarget) { dom.removeAttribute('target'); } } 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 ]); }, onMouseDown: function(e) { var me = this; if (Ext.isIE || e.pointerType === 'touch') { Ext.defer(function() { if (!e.defaultPrevented) { var focusEl = me.getFocusEl(); if (focusEl) { focusEl.focus(); } } }, 1); } if (!me.disabled && e.button === 0) { Ext.button.Manager.onButtonMousedown(me, e); me.addCls(me._pressedCls); } }, onMouseUp: function(e) { var me = this; if (!me.isDestroyed && e.button === 0) { if (!me.pressed) { me.removeCls(me._pressedCls); } } }, onMenuShow: function() { var me = this; me.addCls(me._menuActiveCls); me.fireEvent('menushow', me, me.menu); }, onMenuHide: function(e) { var me = this; me.removeCls(me._menuActiveCls); me.fireEvent('menuhide', me, me.menu); }, onDownKey: function(k, e) { var me = this; if (me.menu && !me.disabled) { me.showMenu(e); e.stopEvent(); return false; } }, updateArrowVisible: function(visible) { var me = this; if (me.rendered) { if (visible) { if (me.menu || me.isSplitButton) { me.split = true; me._addSplitCls(); } } else { me._removeSplitCls(); me.split = false; } } return visible; }, privates: { addOverCls: function() { if (!this.disabled) { this.addCls(this.overCls); } }, _addSplitCls: function() { var me = this; me.btnWrap.addCls(me.getSplitCls()); if (Ext.isOpera12m) { me.addCls(me._operaArrowCls + '-' + me.arrowAlign); } }, getFocusEl: function() { return this.el; }, getTdCls: function() { return Ext.baseCSSPrefix + 'button-' + this.ui + '-' + this.scale + '-cell'; }, removeOverCls: function() { this.removeCls(this.overCls); }, _removeSplitCls: function() { var me = this; me.btnWrap.removeCls(me.getSplitCls()); if (Ext.isOpera12m) { me.removeCls(me._operaArrowCls + '-' + me.arrowAlign); } }, _syncHasIconCls: function() { var me = this, btnEl = me.btnEl, hasIconCls = me._hasIconCls; if (btnEl) { btnEl[me._hasIcon() ? 'addCls' : 'removeCls']([ hasIconCls, hasIconCls + '-' + me.iconAlign ]); } }, _hasIcon: function() { return !!(this.icon || this.iconCls || this.glyph); }, wrapPrimaryEl: function(dom) { this.el = new Ext.dom.ButtonElement(dom); this.callParent([ dom ]); } } }); Ext.define('Ext.tab.Tab', { extend: 'Ext.button.Button', alias: 'widget.tab', requires: [ 'Ext.util.KeyNav' ], isTab: true, tabIndex: -1, baseCls: Ext.baseCSSPrefix + 'tab', closeElOverCls: Ext.baseCSSPrefix + 'tab-close-btn-over', closeElPressedCls: Ext.baseCSSPrefix + 'tab-close-btn-pressed', config: { rotation: 'default', tabPosition: 'top' }, closable: true, closeText: 'Close Tab', active: false, childEls: [ 'closeEl' ], scale: false, ariaRole: 'tab', _btnWrapCls: Ext.baseCSSPrefix + 'tab-wrap', _btnCls: Ext.baseCSSPrefix + 'tab-button', _baseIconCls: Ext.baseCSSPrefix + 'tab-icon-el', _glyphCls: Ext.baseCSSPrefix + 'tab-glyph', _innerCls: Ext.baseCSSPrefix + 'tab-inner', _textCls: Ext.baseCSSPrefix + 'tab-text', _noTextCls: Ext.baseCSSPrefix + 'tab-no-text', _hasIconCls: Ext.baseCSSPrefix + 'tab-icon', _activeCls: Ext.baseCSSPrefix + 'tab-active', _closableCls: Ext.baseCSSPrefix + 'tab-closable', overCls: Ext.baseCSSPrefix + 'tab-over', _pressedCls: Ext.baseCSSPrefix + 'tab-pressed', _disabledCls: Ext.baseCSSPrefix + 'tab-disabled', _rotateClasses: { 1: Ext.baseCSSPrefix + 'tab-rotate-right', 2: Ext.baseCSSPrefix + 'tab-rotate-left' }, _positions: { top: { 'default': 'top', 0: 'top', 1: 'left', 2: 'right' }, right: { 'default': 'top', 0: 'right', 1: 'top', 2: 'bottom' }, bottom: { 'default': 'bottom', 0: 'bottom', 1: 'right', 2: 'left' }, left: { 'default': 'top', 0: 'left', 1: 'bottom', 2: 'top' } }, _defaultRotations: { top: 0, right: 1, bottom: 0, left: 2 }, initComponent: function() { var me = this; if (me.card) { me.setCard(me.card); } me.callParent(arguments); }, getActualRotation: function() { var rotation = this.getRotation(); return (rotation !== 'default') ? rotation : this._defaultRotations[this.getTabPosition()]; }, updateRotation: function() { this.syncRotationAndPosition(); }, updateTabPosition: function() { this.syncRotationAndPosition(); }, syncRotationAndPosition: function() { var me = this, rotateClasses = me._rotateClasses, position = me.getTabPosition(), rotation = me.getActualRotation(), oldRotateCls = me._rotateCls, rotateCls = me._rotateCls = rotateClasses[rotation], oldPositionCls = me._positionCls, positionCls = me._positionCls = me._positions[position][rotation]; if (oldRotateCls !== rotateCls) { if (oldRotateCls) { me.removeCls(oldRotateCls); } if (rotateCls) { me.addCls(rotateCls); } } if (oldPositionCls !== positionCls) { if (oldPositionCls) { me.removeClsWithUI(oldPositionCls); } if (positionCls) { me.addClsWithUI(positionCls); } if (me.rendered) { me.updateFrame(); } } if (me.rendered) { me.setElOrientation(); } }, onAdded: function(container, pos, instanced) { this.callParent([ container, pos, instanced ]); this.syncRotationAndPosition(); }, getTemplateArgs: function() { var me = this, result = me.callParent(); result.closable = me.closable; result.closeText = me.closeText; return result; }, beforeRender: function() { var me = this, tabBar = me.up('tabbar'), tabPanel = me.up('tabpanel'); me.callParent(); if (me.active) { me.addCls(me._activeCls); } me.syncClosableCls(); if (!me.minWidth) { me.minWidth = (tabBar) ? tabBar.minTabWidth : me.minWidth; if (!me.minWidth && tabPanel) { me.minWidth = tabPanel.minTabWidth; } if (me.minWidth && me.iconCls) { me.minWidth += 25; } } if (!me.maxWidth) { me.maxWidth = (tabBar) ? tabBar.maxTabWidth : me.maxWidth; if (!me.maxWidth && tabPanel) { me.maxWidth = tabPanel.maxTabWidth; } } }, onRender: function() { var me = this; me.setElOrientation(); me.callParent(arguments); if (me.closable) { me.closeEl.addClsOnOver(me.closeElOverCls); me.closeEl.addClsOnClick(me.closeElPressedCls); } me.initKeyNav(); }, initKeyNav: function() { var me = this; me.keyNav = new Ext.util.KeyNav(me.el, { enter: me.onEnterKey, del: me.onDeleteKey, scope: me }); }, setElOrientation: function() { var me = this, rotation = me.getActualRotation(), el = me.el; if (rotation) { el.setVertical(rotation === 1 ? 90 : 270); } else { el.setHorizontal(); } }, enable: function(silent) { var me = this; me.callParent(arguments); me.removeCls(me._disabledCls); return me; }, disable: function(silent) { var me = this; me.callParent(arguments); me.addCls(me._disabledCls); return me; }, onDestroy: function() { var me = this; Ext.destroy(me.keyNav); delete me.keyNav; me.callParent(arguments); }, setClosable: function(closable) { var me = this; closable = (!arguments.length || !!closable); if (me.closable !== closable) { me.closable = closable; if (me.card) { me.card.closable = closable; } me.syncClosableCls(); if (me.rendered) { me.syncClosableElements(); me.updateLayout(); } } }, syncClosableElements: function() { var me = this, closeEl = me.closeEl; if (me.closable) { if (!closeEl) { closeEl = me.closeEl = me.btnWrap.insertSibling({ tag: 'a', role: 'presentation', cls: me.baseCls + '-close-btn', href: '#', title: me.closeText }, 'after'); } closeEl.addClsOnOver(me.closeElOverCls); closeEl.addClsOnClick(me.closeElPressedCls); } else if (closeEl) { closeEl.destroy(); delete me.closeEl; } }, syncClosableCls: function() { var me = this, closableCls = me._closableCls; if (me.closable) { me.addCls(closableCls); } else { me.removeCls(closableCls); } }, setCard: function(card) { var me = this; me.card = card; if (card.iconAlign) { me.setIconAlign(card.iconAlign); } if (card.textAlign) { me.setTextAlign(card.textAlign); } me.setText(me.title || card.title); me.setIconCls(me.iconCls || card.iconCls); me.setIcon(me.icon || card.icon); me.setGlyph(me.glyph || card.glyph); }, onCloseClick: function() { var me = this; if (me.fireEvent('beforeclose', me) !== false) { if (me.tabBar) { if (me.tabBar.closeTab(me) === false) { return; } } else { me.fireClose(); } } }, fireClose: function() { this.fireEvent('close', this); }, onEnterKey: function(e) { var me = this; if (me.tabBar) { me.tabBar.onClick(e, me.el); } }, onDeleteKey: function(e) { if (this.closable) { this.onCloseClick(); } }, beforeClick: function(isCloseClick) { if (!isCloseClick) { this.focus(); } }, activate: function(supressEvent) { var me = this; me.active = true; me.addCls(me._activeCls); if (supressEvent !== true) { me.fireEvent('activate', me); } }, deactivate: function(supressEvent) { var me = this; me.active = false; me.removeCls(me._activeCls); if (supressEvent !== true) { me.fireEvent('deactivate', me); } }, privates: { getFramingInfoCls: function() { return this.baseCls + '-' + this.ui + '-' + this._positionCls; }, wrapPrimaryEl: function(dom) { Ext.Button.superclass.wrapPrimaryEl.call(this, dom); } } }); Ext.define('Ext.layout.component.Body', { alias: [ 'layout.body' ], extend: 'Ext.layout.component.Auto', type: 'body', beginLayout: function(ownerContext) { this.callParent(arguments); ownerContext.bodyContext = ownerContext.getEl('body'); }, beginLayoutCycle: function(ownerContext, firstCycle) { var me = this, lastWidthModel = me.lastWidthModel, lastHeightModel = me.lastHeightModel, body = me.owner.body; me.callParent(arguments); if (lastWidthModel && lastWidthModel.fixed && ownerContext.widthModel.shrinkWrap) { body.setWidth(null); } if (lastHeightModel && lastHeightModel.fixed && ownerContext.heightModel.shrinkWrap) { body.setHeight(null); } }, calculateOwnerHeightFromContentHeight: function(ownerContext, contentHeight) { var height = this.callParent(arguments); if (ownerContext.targetContext !== ownerContext) { height += ownerContext.getPaddingInfo().height; } return height; }, calculateOwnerWidthFromContentWidth: function(ownerContext, contentWidth) { var width = this.callParent(arguments); if (ownerContext.targetContext !== ownerContext) { width += ownerContext.getPaddingInfo().width; } return width; }, measureContentWidth: function(ownerContext) { return ownerContext.bodyContext.setWidth(ownerContext.bodyContext.el.dom.offsetWidth, false); }, measureContentHeight: function(ownerContext) { return ownerContext.bodyContext.setHeight(ownerContext.bodyContext.el.dom.offsetHeight, false); }, publishInnerHeight: function(ownerContext, height) { var innerHeight = height - ownerContext.getFrameInfo().height, targetContext = ownerContext.targetContext; if (targetContext !== ownerContext) { innerHeight -= ownerContext.getPaddingInfo().height; } return ownerContext.bodyContext.setHeight(innerHeight, !ownerContext.heightModel.natural); }, publishInnerWidth: function(ownerContext, width) { var innerWidth = width - ownerContext.getFrameInfo().width, targetContext = ownerContext.targetContext; if (targetContext !== ownerContext) { innerWidth -= ownerContext.getPaddingInfo().width; } ownerContext.bodyContext.setWidth(innerWidth, !ownerContext.widthModel.natural); } }); Ext.define('Ext.tab.Bar', { extend: 'Ext.panel.Bar', xtype: 'tabbar', baseCls: Ext.baseCSSPrefix + 'tab-bar', requires: [ 'Ext.tab.Tab', 'Ext.util.Point', 'Ext.layout.component.Body' ], mixins: [ 'Ext.util.FocusableContainer' ], componentLayout: 'body', isTabBar: true, config: { tabRotation: 'default', tabStretchMax: true, activateOnFocus: true }, defaultType: 'tab', plain: false, ensureActiveVisibleOnChange: true, ariaRole: 'tablist', childEls: [ 'body', 'strip' ], _stripCls: Ext.baseCSSPrefix + 'tab-bar-strip', _baseBodyCls: Ext.baseCSSPrefix + 'tab-bar-body', renderTpl: '' + '', _reverseDockNames: { left: 'right', right: 'left' }, _layoutAlign: { top: 'end', right: 'begin', bottom: 'begin', left: 'end' }, initComponent: function() { var me = this, initialLayout = me.initialConfig.layout, initialAlign = initialLayout && initialLayout.align, initialOverflowHandler = initialLayout && initialLayout.overflowHandler; if (me.plain) { me.addCls(me.baseCls + '-plain'); } me.callParent(); me.setLayout({ align: initialAlign || (me.getTabStretchMax() ? 'stretchmax' : me._layoutAlign[me.dock]), overflowHandler: initialOverflowHandler || 'scroller' }); me.on({ click: me.onClick, element: 'el', scope: me }); }, ensureTabVisible: function(tab) { var me = this, tabPanel = me.tabPanel, overflowHandler = me.layout.overflowHandler; if (me.rendered && overflowHandler && me.tooNarrow && overflowHandler.scrollToItem) { if (tab || tab === 0) { if (!tab.isTab) { if (Ext.isNumber(tab)) { tab = this.items.getAt(tab); } else if (tab.isComponent && tabPanel && tabPanel.items.contains(tab)) { tab = tab.tab; } } } if (!tab) { tab = me.activeTab; } if (tab) { overflowHandler.scrollToItem(tab); } } }, initRenderData: function() { var me = this; return Ext.apply(me.callParent(), { bodyCls: me.bodyCls, baseBodyCls: me._baseBodyCls, bodyTargetCls: me.bodyTargetCls, stripCls: me._stripCls, dock: me.dock }); }, setDock: function(dock) { var me = this, items = me.items, ownerCt = me.ownerCt, item, i, ln; items = items && items.items; if (items) { for (i = 0 , ln = items.length; i < ln; i++) { item = items[i]; if (item.isTab) { item.setTabPosition(dock); } } } if (me.rendered) { me.resetItemMargins(); if (ownerCt && ownerCt.isHeader) { ownerCt.resetItemMargins(); } me.needsScroll = true; } me.callParent([ dock ]); }, updateTabRotation: function(tabRotation) { var me = this, items = me.items, i, ln, item; items = items && items.items; if (items) { for (i = 0 , ln = items.length; i < ln; i++) { item = items[i]; if (item.isTab) { item.setRotation(tabRotation); } } } if (me.rendered) { me.resetItemMargins(); me.needsScroll = true; me.updateLayout(); } }, onRender: function() { var me = this; me.callParent(); if (Ext.isIE8 && me.vertical) { me.el.on({ mousemove: me.onMouseMove, scope: me }); } }, afterLayout: function() { this.adjustTabPositions(); this.callParent(arguments); }, onAdd: function(tab, pos) { var fn = this.onTabContentChange; if (this.ensureActiveVisibleOnChange) { tab.barListeners = tab.on({ scope: this, destroyable: true, glyphchange: fn, iconchange: fn, textchange: fn }); } this.callParent([ tab, pos ]); }, onAdded: function(container, pos, instanced) { if (container.isHeader) { this.addCls(container.baseCls + '-' + container.ui + '-tab-bar'); } this.callParent([ container, pos, instanced ]); }, onRemove: function(tab, destroying) { var me = this; if (me.ensureActiveVisibleOnChange) { if (!destroying) { tab.barListeners.destroy(); } tab.barListeners = null; } if (tab === me.previousTab) { me.previousTab = null; } me.callParent([ tab, destroying ]); }, onRemoved: function(destroying) { var ownerCt = this.ownerCt; if (ownerCt.isHeader) { this.removeCls(ownerCt.baseCls + '-' + ownerCt.ui + '-tab-bar'); } this.callParent([ destroying ]); }, onTabContentChange: function(tab) { if (tab === this.activeTab) { this.ensureTabVisible(tab); } }, afterComponentLayout: function(width) { var me = this, needsScroll = me.needsScroll, overflowHandler = me.layout.overflowHandler; me.callParent(arguments); if (overflowHandler && needsScroll && me.tooNarrow && overflowHandler.scrollToItem) { overflowHandler.scrollToItem(me.activeTab); } delete me.needsScroll; }, onMouseMove: function(e) { var me = this, overTab = me._overTab, tabInfo, tab; if (e.getTarget('.' + Ext.baseCSSPrefix + 'box-scroller')) { return; } tabInfo = me.getTabInfoFromPoint(e.getXY()); tab = tabInfo.tab; if (tab !== overTab) { if (overTab && overTab.rendered) { overTab.onMouseLeave(e); me._overTab = null; } if (tab) { tab.onMouseEnter(e); me._overTab = tab; if (!tab.disabled) { me.el.setStyle('cursor', 'pointer'); } } else { me.el.setStyle('cursor', 'default'); } } }, onMouseLeave: function(e) { var overTab = this._overTab; if (overTab && overTab.rendered) { overTab.onMouseLeave(e); } }, getTabInfoFromPoint: function(xy) { var me = this, tabs = me.items.items, length = tabs.length, innerCt = me.layout.innerCt, innerCtXY = innerCt.getXY(), point = new Ext.util.Point(xy[0], xy[1]), i = 0, lastBox, tabRegion, closeEl, close, closeXY, closeX, closeY, closeWidth, closeHeight, tabX, tabY, tabWidth, tabHeight, closeRegion, isTabReversed, direction, tab; for (; i < length; i++) { tab = tabs[i]; lastBox = tab.lastBox; if (!lastBox || !tab.isTab) { continue; } tabX = innerCtXY[0] + lastBox.x; tabY = innerCtXY[1] - innerCt.dom.scrollTop + lastBox.y; tabWidth = lastBox.width; tabHeight = lastBox.height; tabRegion = new Ext.util.Region(tabY, tabX + tabWidth, tabY + tabHeight, tabX); if (tabRegion.contains(point)) { closeEl = tab.closeEl; if (closeEl) { if (me._isTabReversed === undefined) { me._isTabReversed = isTabReversed = (tab.btnWrap.dom.currentStyle.filter.indexOf('rotation=2') !== -1); } direction = isTabReversed ? this._reverseDockNames[me.dock] : me.dock; closeWidth = closeEl.getWidth(); closeHeight = closeEl.getHeight(); closeXY = me.getCloseXY(closeEl, tabX, tabY, tabWidth, tabHeight, closeWidth, closeHeight, direction); closeX = closeXY[0]; closeY = closeXY[1]; closeRegion = new Ext.util.Region(closeY, closeX + closeWidth, closeY + closeHeight, closeX); close = closeRegion.contains(point); } break; } } return { tab: tab, close: close }; }, getCloseXY: function(closeEl, tabX, tabY, tabWidth, tabHeight, closeWidth, closeHeight, direction) { var closeXY = closeEl.getXY(), closeX, closeY; if (direction === 'right') { closeX = tabX + tabWidth - ((closeXY[1] - tabY) + closeHeight); closeY = tabY + (closeXY[0] - tabX); } else { closeX = tabX + (closeXY[1] - tabY); closeY = tabY + tabX + tabHeight - closeXY[0] - closeWidth; } return [ closeX, closeY ]; }, closeTab: function(toClose) { var me = this, card = toClose.card, tabPanel = me.tabPanel, toActivate; if (card && card.fireEvent('beforeclose', card) === false) { return false; } toActivate = me.findNextActivatable(toClose); Ext.suspendLayouts(); if (tabPanel && card) { delete toClose.ownerCt; card.fireEvent('close', card); tabPanel.remove(card); if (!tabPanel.getComponent(card)) { toClose.fireClose(); me.remove(toClose); } else { toClose.ownerCt = me; Ext.resumeLayouts(true); return false; } } if (toActivate) { if (tabPanel) { tabPanel.setActiveTab(toActivate.card); } else { me.setActiveTab(toActivate); } toActivate.focus(); } Ext.resumeLayouts(true); }, findNextActivatable: function(toClose) { var me = this; if (toClose.active && me.items.getCount() > 1) { return (me.previousTab && me.previousTab !== toClose && !me.previousTab.disabled) ? me.previousTab : (toClose.next('tab[disabled=false]') || toClose.prev('tab[disabled=false]')); } }, setActiveTab: function(tab, initial) { var me = this; if (!tab.disabled && tab !== me.activeTab) { if (me.activeTab) { if (me.activeTab.isDestroyed) { me.previousTab = null; } else { me.previousTab = me.activeTab; me.activeTab.deactivate(); me.deactivateFocusable(me.activeTab); } } tab.activate(); me.activateFocusable(tab); me.activeTab = tab; me.needsScroll = true; if (!initial) { me.fireEvent('change', me, tab, tab.card); me.updateLayout(); } } }, privates: { adjustTabPositions: function() { var me = this, items = me.items.items, i = items.length, tab, lastBox, el, rotation, prop; if (!Ext.isIE8) { prop = me._getTabAdjustProp(); while (i--) { tab = items[i]; el = tab.el; lastBox = tab.lastBox; rotation = tab.isTab ? tab.getActualRotation() : 0; if (rotation === 1 && tab.isVisible()) { el.setStyle(prop, (lastBox.x + lastBox.width) + 'px'); } else if (rotation === 2 && tab.isVisible()) { el.setStyle(prop, (lastBox.x - lastBox.height) + 'px'); } } } }, applyTargetCls: function(targetCls) { this.bodyTargetCls = targetCls; }, _getTabAdjustProp: function() { return 'left'; }, getTargetEl: function() { return this.body || this.frameBody || this.el; }, onClick: function(e, target) { var me = this, tabEl, tab, isCloseClick, tabInfo; if (e.getTarget('.' + Ext.baseCSSPrefix + 'box-scroller')) { return; } if (Ext.isIE8 && me.vertical) { tabInfo = me.getTabInfoFromPoint(e.getXY()); tab = tabInfo.tab; isCloseClick = tabInfo.close; } else { tabEl = e.getTarget('.' + Ext.tab.Tab.prototype.baseCls); tab = tabEl && Ext.getCmp(tabEl.id); isCloseClick = tab && tab.closeEl && (target === tab.closeEl.dom); } if (isCloseClick) { e.preventDefault(); } if (tab && tab.isDisabled && !tab.isDisabled()) { tab.beforeClick(isCloseClick); if (tab.closable && isCloseClick) { tab.onCloseClick(); } else { me.doActivateTab(tab); } } }, doActivateTab: function(tab) { var tabPanel = this.tabPanel; if (tabPanel) { if (!tab.disabled) { tabPanel.setActiveTab(tab.card); } } else { this.setActiveTab(tab); } }, onFocusableContainerFocus: function(e) { var me = this, mixin = me.mixins.focusablecontainer, child; child = mixin.onFocusableContainerFocus.call(me, e); if (child && child.isTab) { me.doActivateTab(child); } }, onFocusableContainerFocusEnter: function(e) { var me = this, mixin = me.mixins.focusablecontainer, child; child = mixin.onFocusableContainerFocusEnter.call(me, e); if (child && child.isTab) { me.doActivateTab(child); } }, focusChild: function(child, forward) { var me = this, mixin = me.mixins.focusablecontainer, nextChild; nextChild = mixin.focusChild.call(me, child, forward); if (me.activateOnFocus && nextChild && nextChild.isTab) { me.doActivateTab(nextChild); } } } }); Ext.define('Ext.tab.Panel', { extend: 'Ext.panel.Panel', alias: 'widget.tabpanel', alternateClassName: [ 'Ext.TabPanel' ], requires: [ 'Ext.layout.container.Card', 'Ext.tab.Bar' ], config: { tabBar: undefined, tabPosition: 'top', tabRotation: 'default', tabStretchMax: true }, removePanelHeader: true, plain: false, itemCls: Ext.baseCSSPrefix + 'tabpanel-child', minTabWidth: undefined, maxTabWidth: undefined, deferredRender: true, _defaultTabRotation: { top: 0, right: 1, bottom: 0, left: 2 }, initComponent: function() { var me = this, activeTab = me.activeTab !== null ? (me.activeTab || 0) : null, dockedItems = me.dockedItems, header = me.header, tabBarHeaderPosition = me.tabBarHeaderPosition, tabBar = me.getTabBar(), headerItems; me.layout = new Ext.layout.container.Card(Ext.apply({ owner: me, deferredRender: me.deferredRender, itemCls: me.itemCls, activeItem: activeTab }, me.layout)); if (tabBarHeaderPosition != null) { header = me.header = Ext.apply({}, header); headerItems = header.items = (header.items ? header.items.slice() : []); header.itemPosition = tabBarHeaderPosition; headerItems.push(tabBar); header.hasTabBar = true; } else { dockedItems = [].concat(me.dockedItems || []); dockedItems.push(tabBar); me.dockedItems = dockedItems; } me.callParent(arguments); activeTab = me.activeTab = me.getComponent(activeTab); if (activeTab) { tabBar.setActiveTab(activeTab.tab, true); } }, onRender: function() { var items = this.items.items, len = items.length, i; this.callParent(arguments); for (i = 0; i < len; ++i) { items[i].getBind(); } }, setActiveTab: function(card) { var me = this, previous; if (!Ext.isObject(card) || card.isComponent) { card = me.getComponent(card); } previous = me.getActiveTab(); if (card) { Ext.suspendLayouts(); if (!card.isComponent) { card = me.add(card); } if (previous === card || me.fireEvent('beforetabchange', me, card, previous) === false) { Ext.resumeLayouts(true); return previous; } me.activeTab = card; me.layout.setActiveItem(card); card = me.activeTab = me.layout.getActiveItem(); if (card && card !== previous) { me.tabBar.setActiveTab(card.tab); Ext.resumeLayouts(true); if (previous !== card) { me.fireEvent('tabchange', me, card, previous); } } else { Ext.resumeLayouts(true); } return card; } return previous; }, setActiveItem: function(item) { return this.setActiveTab(item); }, getActiveTab: function() { var me = this, result = me.getComponent(me.activeTab); if (result && me.items.indexOf(result) !== -1) { me.activeTab = result; } else { me.activeTab = undefined; } return me.activeTab; }, applyTabBar: function(tabBar) { var me = this, dock = (me.tabBarHeaderPosition != null) ? me.getHeaderPosition() : me.getTabPosition(); return new Ext.tab.Bar(Ext.apply({ ui: me.ui, dock: dock, tabRotation: me.getTabRotation(), vertical: (dock === 'left' || dock === 'right'), plain: me.plain, tabStretchMax: me.getTabStretchMax(), tabPanel: me }, tabBar)); }, updateHeaderPosition: function(headerPosition, oldHeaderPosition) { var tabBar = this.getTabBar(); if (tabBar && (this.tabBarHeaderPosition != null)) { tabBar.setDock(headerPosition); } this.callParent([ headerPosition, oldHeaderPosition ]); }, updateTabPosition: function(tabPosition) { var tabBar = this.getTabBar(); if (tabBar && (this.tabBarHeaderPosition == null)) { tabBar.setDock(tabPosition); } }, updateTabRotation: function(tabRotation) { var tabBar = this.getTabBar(); if (tabBar) { tabBar.setTabRotation(tabRotation); } }, onAdd: function(item, index) { var me = this, cfg = Ext.apply({}, item.tabConfig), tabBar = me.getTabBar(), defaultConfig = { xtype: 'tab', title: item.title, icon: item.icon, iconCls: item.iconCls, glyph: item.glyph, ui: tabBar.ui, card: item, disabled: item.disabled, closable: item.closable, hidden: item.hidden && !item.hiddenByLayout, tooltip: item.tooltip, tabBar: tabBar, tabPosition: tabBar.dock, rotation: tabBar.getTabRotation() }; if (item.closeText !== undefined) { defaultConfig.closeText = item.closeText; } cfg = Ext.applyIf(cfg, defaultConfig); item.tab = me.tabBar.insert(index, cfg); item.on({ scope: me, enable: me.onItemEnable, disable: me.onItemDisable, beforeshow: me.onItemBeforeShow, iconchange: me.onItemIconChange, iconclschange: me.onItemIconClsChange, glyphchange: me.onItemGlyphChange, titlechange: me.onItemTitleChange }); if (item.isPanel) { if (me.removePanelHeader) { if (item.rendered) { if (item.header) { item.header.hide(); } } else { item.header = false; } } if (item.isPanel && me.border) { item.setBorder(false); } } if (me.rendered) { item.getBind(); } if (me.rendered && me.loader && me.activeTab === undefined && me.layout.activeItem !== null) { me.setActiveTab(0); } }, onMove: function(item, fromIdx, toIdx) { var tabBar = this.getTabBar(); this.callParent([ item, fromIdx, toIdx ]); if (tabBar.items.indexOf(item.tab) !== toIdx) { tabBar.move(item.tab, toIdx); } }, onItemEnable: function(item) { item.tab.enable(); }, onItemDisable: function(item) { item.tab.disable(); }, onItemBeforeShow: function(item) { if (item !== this.activeTab) { this.setActiveTab(item); return false; } }, onItemGlyphChange: function(item, newGlyph) { item.tab.setGlyph(newGlyph); }, onItemIconChange: function(item, newIcon) { item.tab.setIcon(newIcon); }, onItemIconClsChange: function(item, newIconCls) { item.tab.setIconCls(newIconCls); }, onItemTitleChange: function(item, newTitle) { item.tab.setText(newTitle); }, onRemove: function(item, destroying) { var me = this; item.un({ scope: me, enable: me.onItemEnable, disable: me.onItemDisable, beforeshow: me.onItemBeforeShow, iconchange: me.onItemIconChange, iconclschange: me.onItemIconClsChange, glyphchange: me.onItemGlyphChange, titlechange: me.onItemTitleChange }); if (item.tab && !me.destroying && item.tab.ownerCt === me.tabBar) { me.tabBar.remove(item.tab); } }, privates: { doRemove: function(item, autoDestroy) { var me = this, toActivate; if (me.removingAll || me.destroying || me.items.getCount() === 1) { me.activeTab = null; } else if (item.tab && (toActivate = me.tabBar.items.indexOf(me.tabBar.findNextActivatable(item.tab))) !== -1) { me.setActiveTab(toActivate); } this.callParent(arguments); if (item.tab) { delete item.tab.card; delete item.tab; } } } }); Ext.define('Ext.app.bindinspector.Environment', { requires: [ 'Ext.util.Collection' ], getCmp: function(id) { return this.components.get(id); }, getVM: function(id) { return this.viewModels.get(id); }, getInheritedVM: function(comp) { var vm = comp.viewModel, parent = comp.parent; if (vm) { return vm; } if (parent) { return this.getInheritedVM(this.getCmp(parent)); } return null; }, captureSnapshot: function() { var all = Ext.ComponentManager.getAll(), len = all.length, components = [], i, comp; this.models = {}; for (i = 0; i < len; ++i) { comp = all[i]; if (comp.afterRender && this.isRootComponent(comp)) { components.push(this.buildComponent(comp)); } } return { isBindData: true, version: Ext.getVersion().version, models: this.models, components: components }; }, serializeModel: function(Model) { var models = this.models, name = Model.entityName; if (!models[name]) { models[name] = Ext.Array.map(Model.getFields(), function(field) { return { name: field.getName(), type: field.getType() }; }); } }, isRootComponent: function(c) { var owner = c.getRefOwner(); if (owner || c.isBindInspector || c === Ext.MessageBox || c.is('quicktip')) { return false; } return true; }, buildComponent: function(comp) { var childItems = comp.getRefItems ? comp.getRefItems() : null, viewModel = comp.getViewModel(), bind = comp.getBind(), id = comp.id, len, i, o, child; if (bind) { bind = this.buildBind(bind); } o = { id: id, xtype: comp.getXType(), publishes: comp.getPublishes(), viewModel: viewModel ? this.buildViewModel(viewModel, comp) : null, bindings: bind || null, reference: comp.reference || null, items: [] }; if (childItems) { for (i = 0 , len = childItems.length; i < len; ++i) { if (childItems[i].afterRender) { child = this.buildComponent(childItems[i]); child.parent = id; o.items.push(child); } } } return o; }, buildBind: function(bind) { var out = {}, key, o, bindInfo, name, stub; for (key in bind) { o = bind[key]; stub = o.stub; bindInfo = { id: o.id, value: this.serializeValue(o.getRawValue()), stub: stub ? { id: stub.id, name: stub.name } : null }; if (o.isTemplateBinding) { bindInfo.isTemplateBinding = true; bindInfo.tokens = []; Ext.Array.forEach(o.tokens, function(token) { bindInfo.tokens.push(token.split('.')); }, this); bindInfo.descriptor = o.tpl.text; } else if (o.isMultiBinding) { bindInfo.isMultiBinding = true; } else { if (stub) { name = this.buildStubName(stub); bindInfo.tokens = name.split('.'); bindInfo.descriptor = '{' + name + '}'; } } out[key] = bindInfo; } return out; }, buildStubName: function(stub) { var parent = stub.parent, name = ''; if (parent && !parent.isRootStub) { name = this.buildStubName(parent) + '.'; } return name + stub.name; }, buildViewModel: function(vm, comp) { var parent = vm.getParent(); return { id: vm.getId(), view: comp.id, parent: parent ? parent.getId() : null, data: this.serializeValue(vm.getData(), true), rootStub: this.buildStub(vm.getRoot()) }; }, buildStub: function(stub, isLinkChild) { var o = {}, children = stub.children, isLink = stub.isLinkStub, outChildren = {}, key, hasAny, child, sameTarget; if (!stub.isRootStub) { o.name = stub.name; o.parent = stub.parent ? stub.parent.id : null; o.isLoading = stub.isLoading(); o.bindCount = (stub.bindings && stub.bindings.length) || 0; o.cumulativeBindCount = o.bindCount; o.value = this.serializeValue(stub.getRawValue()); if (isLink) { sameTarget = stub.target === stub.owner; o.linkInfo = { sameTarget: sameTarget, descriptor: stub.linkDescriptor, value: this.serializeValue(stub.binding.getValue()) }; isLinkChild = true; } } else { o.name = ''; o.isLoading = false; o.bindCount = o.cumulativeBindCount = 0; } if (children) { for (key in children) { hasAny = true; child = this.buildStub(children[key], isLinkChild); outChildren[key] = child; o.cumulativeBindCount += child.cumulativeBindCount; } } if (hasAny) { o.children = outChildren; } return o; }, createModel: function(entityName, data) { var Model = Ext.app.bindinspector.noconflict[entityName]; return new Model(data); }, unpackSnapshot: function(data) { this.components = new Ext.util.Collection(); this.viewModels = new Ext.util.Collection(); Ext.Object.each(data.models, function(key, fields) { Ext.define('Ext.app.bindinspector.noconflict.' + key, { extend: 'Ext.app.bindinspector.noconflict.BaseModel', fields: fields }); }); Ext.Array.forEach(data.components, function(comp) { this.unpackComponent(comp, this.components, this.viewModels); }, this); this.rootComponents = data.components; }, unpackComponent: function(comp, allComponents, allViewModels) { var vm = comp.viewModel, items = comp.items, bindings = comp.bindings, len, i, parentVM, parentData, data, key, binding; allComponents.add(comp); if (bindings) { for (key in bindings) { binding = bindings[key]; binding.value = this.deserializeValue(binding.value); } } if (vm) { allViewModels.add(vm); parentVM = this.getVM(vm.parent); if (parentVM) { parentData = Ext.Object.chain(parentVM.data); } data = this.deserializeValue(vm.data); if (parentData) { data = Ext.apply(parentData, data); } vm.data = data; this.deserializeStub(vm.rootStub); } if (items) { for (i = 0 , len = items.length; i < len; ++i) { this.unpackComponent(items[i], allComponents, allViewModels); } } }, serializeValue: function(value, checkHasOwn) { var info = {}, type, key, item, childInfo, model; if (value && value.constructor === Object) { type = 'object'; info.value = {}; for (key in value) { if (!(checkHasOwn && !value.hasOwnProperty(key))) { childInfo = this.serializeValue(value[key], checkHasOwn); item = { type: childInfo.type, value: childInfo.value }; if (childInfo.entityName) { item.entityName = childInfo.entityName; } info.value[key] = item; } } } else if (value && value.isModel) { type = 'model'; info.entityName = value.entityName; this.serializeModel(value.self); info.value = this.serializeValue(value.data); } else if (value && value.isStore) { type = 'store'; model = value.getModel(); info.entityName = model.entityName; if (model.entityName) { this.serializeModel(model); } } else if (Ext.isDate(value)) { type = 'date'; info.value = Ext.Date.format(value, 'c'); } else if (Ext.isArray(value)) { type = 'array'; info.value = []; Ext.Array.forEach(value, function(item) { info.value.push(this.serializeValue(item)); }, this); } else { type = Ext.typeOf(value); info.value = value; } info.type = type; return info; }, deserializeValue: function(info) { var type = info.type, raw = info.value, out, key; if (type === 'null') { out = null; } else if (type === 'undefined') { out = undefined; } else if (type === 'string' || type === 'boolean' || type === 'number') { out = raw; } else if (type === 'date') { out = Ext.Date.parse(raw, 'c'); } else if (type === 'object') { out = {}; for (key in raw) { out[key] = this.deserializeValue(raw[key]); } } else if (type === 'model') { out = this.createModel(info.entityName, this.deserializeValue(raw)); } else if (type === 'store') { out = { isStore: true, entityName: info.entityName }; } else if (type === 'array') { out = []; Ext.Array.forEach(raw, function(item) { out.push(this.deserializeValue(item)); }, this); } return out; }, deserializeStub: function(stub) { var children = stub.children, linkInfo = stub.linkInfo, key; if (stub.value) { stub.value = this.deserializeValue(stub.value); } if (linkInfo) { linkInfo.value = this.deserializeValue(linkInfo.value); } if (children) { for (key in children) { this.deserializeStub(children[key]); } } } }); Ext.define('Ext.app.bindinspector.ViewModelDetail', { extend: 'Ext.tree.Panel', alias: 'widget.bindinspector-viewmodeldetail', rootVisible: false, cls: Ext.baseCSSPrefix + 'bindinspector-viewmodeldetail', inheritedCls: Ext.baseCSSPrefix + 'bindinspector-inherited', notInheritedCls: Ext.baseCSSPrefix + 'bindinspector-not-inherited', highlightedCls: Ext.baseCSSPrefix + 'bindinspector-highlighted', unhighlightedCls: Ext.baseCSSPrefix + 'bindinspector-unhighlighted', lastItemCls: Ext.baseCSSPrefix + 'bindinspector-last-item', initComponent: function() { var me = this, vm = me.vm, title = 'VM    ⇒    ', env = me.up('bindinspector-container').env, comp = env.getCmp(vm.view); if (comp.reference) { title += '[' + comp.reference + '] • '; } me.title = title += comp.id; me.viewConfig = { getRowClass: function(record, index, rowParams, store) { var data = record.get('hasData'), stub = record.get('hasStub'), cls = [], highlighted = record.get('highlighted'); if (record.get('inherited')) { cls.push(me.inheritedCls); } else { cls.push(me.notInheritedCls); } if (highlighted === true) { cls.push(me.highlightedCls); } else if (highlighted === -1) { cls.push(me.unhighlightedCls); } if (index === store.getCount() - 1) { cls.push(me.lastItemCls); } if (data && (!stub || record.get('cumulativeBindCount') === 0)) { cls.push(me.dataOnlyCls); } return cls.join(' '); } }; me.store = { model: me.Model, root: { text: 'Root', expanded: true, children: me.setupData(vm, vm.data, vm.rootStub) } }; me.columns = [ { width: 40, tdCls: Ext.baseCSSPrefix + 'bindinspector-indicator-col', align: 'center', scope: me, renderer: me.renderIndicator }, { flex: 1, xtype: 'treecolumn', dataIndex: 'name', text: 'Name', scope: me, renderer: me.renderName }, { flex: 1, dataIndex: 'value', text: 'Value', scope: me, renderer: Ext.app.bindinspector.Util.valueRenderer }, { text: 'Bind #', width: 64, align: 'center', renderer: me.renderBindCount, scope: me }, { width: 40, isSearch: true, renderer: me.dataSrcConsumerRenderer, scope: me } ]; me.callParent(); me.on('cellclick', me.onSearchCellClick, me); }, dataOnlyNode: 'This item contains data but has nothing requesting the value', stubOnlyNode: 'This item has the value requested but no data backing it', dataPointLoading: 'Data point is loading (at the time the app snapshot was captured)', dataPointLoadingCls: Ext.baseCSSPrefix + 'bindinspector-isloading', zeroBindingCls: Ext.baseCSSPrefix + 'bi-zero-bind-count', dataOnlyCls: Ext.baseCSSPrefix + 'bindinspector-data-only', stubOnlyCls: Ext.baseCSSPrefix + 'bindinspector-stub-only', onSearchCellClick: function(view, td, cellIndex, rec, tr, rowIndex, e) { if (view.getHeaderCt().getHeaderAtIndex(cellIndex).isSearch) { this.up('bindinspector-container').fireEvent('vmSearchClick', rec); } }, getFirstTierRec: function(rec) { var isFirstTier = rec.parentNode.isRoot(), firstTier; if (!isFirstTier) { rec.bubble(function(ni) { if (ni.parentNode.isRoot()) { firstTier = ni; return false; } }); } return isFirstTier ? rec : firstTier; }, dataSrcConsumerRenderer: function(v, meta, rec) { var firstTier = this.getFirstTierRec(rec), firstTierName = firstTier.get('name'); meta.tdCls = Ext.baseCSSPrefix + 'bindinspector-data-search-cell'; meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="Click to indicate within the Component List all ViewModels with a data property of  ' + firstTierName + '"'; }, renderIndicator: function(v, meta, rec) { var ownerVMs = rec.get('ownerVMs'), len = ownerVMs.length, direct = false, inherited = false, val = '', firstTier = this.getFirstTierRec(rec), isFirstTier = firstTier === rec, firstTierName = firstTier.get('name'), vmPlural; Ext.Array.forEach(ownerVMs, function(vm) { if (vm.id === vm.thisVM) { direct = true; } if (vm.id !== vm.thisVM) { inherited = true; } }); if (direct && inherited) { val = Ext.util.Format.format('{0}', isFirstTier ? '◓' : '-'); vmPlural = len > 1 ? 'VMs' : 'VM'; meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + firstTierName + '  provided by this VM and ' + (len - 1) + ' ancestor ' + vmPlural + '"'; } else if (direct) { val = isFirstTier ? '●' : ''; meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + firstTierName + '  is provided by this VM"'; } else if (inherited) { val = isFirstTier ? '○' : ''; vmPlural = len > 1 ? 'VMs' : 'VM'; meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + firstTierName + '  is provided by ' + len + ' ancestor ' + vmPlural + '"'; } return val; }, renderBindCount: function(v, meta, rec) { var len = rec.get('children').length, bindCount = rec.get('bindCount') || 0, total, bindingsText; v = bindCount; if (v === 0) { v = '' + v + ''; } if (len) { total = rec.get('cumulativeBindCount') || '?'; if (total === 0 || total === '?') { v += ' / ' + total + ''; } else { v += ' / ' + total; } } bindingsText = 'Bindings Count = ' + bindCount + ''; if (total && total !== 0 && total !== '?') { bindingsText += '
Cumulative Bindings Count = ' + total + ''; } meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + bindingsText + '"'; return v; }, renderName: function(v, meta, rec) { var me = this, data = rec.get('hasData'), stub = rec.get('hasStub'), tip = ''; if (rec.get('isLoading')) { meta.tdCls = me.dataPointLoadingCls; tip += me.dataPointLoading; } else if (data && (!stub || rec.get('cumulativeBindCount') === 0)) { tip += me.dataOnlyNode; } else if (stub && !data) { meta.tdCls = me.stubOnlyCls; tip += me.stubOnlyNode; } if (tip !== '') { meta.tdAttr = 'data-qclass="' + Ext.baseCSSPrefix + 'componentlist-tip" data-qtip="' + tip + '"'; } return v; }, setupData: function(vm, data, stub, inherited, ownerVMs) { var merged = {}, out = [], dataMap = vm.dataMap, dm = [], item, children, stubChild, key, stopDigging, linkInfo; if (data && Ext.isObject(data)) { if (data.isModel) { data = data.data; stopDigging = true; } else if (data.isStore) { stopDigging = true; data = null; } if (data) { for (key in data) { if (!ownerVMs) { dm = dataMap[key] ? dataMap[key].ownerVMs : []; } item = { name: key, value: data[key], inherited: Ext.isDefined(inherited) ? inherited : !data.hasOwnProperty(key), ownerVMs: Ext.isDefined(ownerVMs) ? ownerVMs : [], hasData: true }; Ext.Array.forEach(dm, function(v) { item.ownerVMs.push({ id: v.id, view: v.view, thisVM: vm.id }); }); stubChild = Ext.app.bindinspector.Util.getChildStub(key, stub); if (stubChild) { item.hasStub = true; item.isLoading = stubChild.isLoading; item.iconCls = stubChild.isLoading ? this.dataPointLoadingCls : ''; item.bindCount = stubChild.bindCount; item.cumulativeBindCount = stubChild.cumulativeBindCount; item.stub = stubChild; } merged[key] = item; } } } if (stub) { children = stub.children; for (key in children) { stubChild = children[key]; item = merged[key]; if (!item) { item = { name: key, value: stubChild.value || undefined, inherited: inherited || false, ownerVMs: ownerVMs || [], hasData: false, hasStub: true, isLoading: stubChild.isLoading, iconCls: stubChild.isLoading ? this.dataPointLoadingCls : '', bindCount: stubChild.bindCount, cumulativeBindCount: stubChild.cumulativeBindCount, stub: stubChild }; linkInfo = stubChild.linkInfo; if (linkInfo && linkInfo.sameTarget) { item.value = linkInfo.value; item.hasData = item.value !== undefined; } merged[key] = item; } } } for (key in merged) { item = merged[key]; item.children = this.setupData(vm, item.value, item.stub, item.inherited, item.ownerVMs); delete item.stub; if (item.children && item.children.length) { item.expanded = true; item.leaf = false; } else { item.leaf = true; } out.push(merged[key]); } return out; } }, function() { this.prototype.Model = Ext.define(null, { extend: 'Ext.data.TreeModel', fields: [ 'name', 'value', 'inherited', 'hasData', 'hasStub', 'isLoading', 'bindCount', 'cumulativeBindCount', 'highlighted' ] }); }); Ext.define('Ext.app.bindinspector.noconflict.BaseModel', { extend: 'Ext.data.Model', schema: { id: 'Ext_app_bindinspector', namespace: 'Ext.app.bindinspector' } }); Ext.define('Ext.app.bindinspector.Container', { extend: 'Ext.container.Container', alias: 'widget.bindinspector-container', requires: [ 'Ext.layout.container.Border', 'Ext.tab.Panel', 'Ext.app.bindinspector.ComponentDetail', 'Ext.app.bindinspector.ComponentList', 'Ext.app.bindinspector.Environment', 'Ext.app.bindinspector.Util', 'Ext.app.bindinspector.ViewModelDetail', 'Ext.app.bindinspector.noconflict.BaseModel' ], isBindInspector: true, referenceHolder: true, layout: 'border', cls: Ext.baseCSSPrefix + 'bindinspector-container', componentPreviewDefault: { xtype: 'container', cls: Ext.baseCSSPrefix + 'bindinspector-prev-default', padding: 20, layout: { type: 'hbox', align: 'middle', pack: 'center' }, items: [ { xtype: 'component', flex: 1, html: 'Select a component with bindings from the ComponentList to view the bindings details along with the component\'s inherited ViewModel' } ] }, initComponent: function() { var me = this; Ext.data.schema.Schema.get('Ext_app_bindinspector').clear(); me.items = [ { xtype: 'bindinspector-componentlist', reference: 'componentList', region: 'west', width: 400, split: true, collapsible: true, components: me.env.rootComponents, listeners: { scope: me, componentdblclick: me.onComponentDblclick, componentselect: me.onComponentSelect } }, { xtype: 'tabpanel', region: 'center', reference: 'tabs', items: [ { title: 'Preview', reference: 'preview', layout: 'fit', items: [ me.componentPreviewDefault ] } ], listeners: { add: function() { this.getTabBar().setVisible(this.items.getCount() > 1); }, remove: function() { this.getTabBar().setVisible(this.items.getCount() > 1); } } } ]; me.callParent(); me.on('vmSearchClick', me.onVMSearchClick, me); }, onVMSearchClick: function(rec) { var componentList = this.lookupReference('componentList'), store = componentList.getStore(), ownerVMs = rec.get('ownerVMs'), sourceVMs = [], bindCount = rec.get('bindCount'), names = [], consumerNodes = [], query = [], source, descriptor; store.suspendEvents(); componentList.clearVMSearchIndicators(); Ext.Array.forEach(ownerVMs, function(vm) { source = store.getById(vm.view); source.set('isSrcVM', rec); sourceVMs.push(source); }); store.resumeEvents(); componentList.getView().refresh(); componentList.indicatedVM = sourceVMs; if (bindCount > 0) { rec.bubble(function(node) { var nodeName = node.get('name'); if (nodeName) { names.push(nodeName); } }); descriptor = names.reverse().join('.'); componentList.getStore().getRootNode().cascadeBy(function(node) { if (node.get('hasBindings')) { Ext.Array.forEach(node.get('bindData'), function(binding) { var tokenStr = []; if (binding.tokens) { Ext.Array.forEach(binding.tokens, function(token) { if (Ext.isArray(token)) { Ext.Array.forEach(token, function(t) { tokenStr.push(t); }); } else { tokenStr.push(token); } }); } if (tokenStr.join('.') === descriptor) { consumerNodes.push(node); } }); } }); } Ext.Array.forEach(consumerNodes.concat(sourceVMs), function(node) { query.push(node.getId()); }); componentList.expand(); componentList.filterComponentTree(null, query); Ext.Array.forEach(sourceVMs, function(src) { if (!Ext.Array.contains(consumerNodes)) { src.set('filtervisible', false); } }); componentList.down('#srcVMIndicator').show(); componentList.down('#queryFieldTb').hide(); componentList.down('#vmQueryResultsTb').show(); }, onComponentSelect: function(tree, rec, node) { var me = this, id = rec.getId(), preview = me.lookupReference('preview'); if (preview.referringID !== id) { Ext.suspendLayouts(); preview.removeAll(); preview.add({ xtype: 'bindinspector-componentdetail', env: me.env, component: me.env.getCmp(id) }); Ext.resumeLayouts(true); preview.referringID = id; } preview.show(); }, onComponentDblclick: function(tree, rec, node) { var id = rec.id, tabId = 'bindtab-' + id, tabs = this.lookupReference('tabs'), tab = tabs.items.get(tabId), component, reference; if (!tab) { component = this.env.getCmp(id); reference = component.reference; tab = tabs.add({ xtype: 'bindinspector-componentdetail', env: this.env, itemId: tabId, title: reference ? '[' + reference + '] ' + id : id, closable: true, component: component }); } tabs.setActiveTab(tab); }, buildVMDataMap: function(vm) { var env = this.env, currVM = vm, dataMap = vm.dataMap, viewModels = [], data, isDirect; if (!dataMap) { dataMap = vm.dataMap = {}; while (currVM) { viewModels.push(currVM); currVM = env.getVM(currVM.parent); } Ext.Array.forEach(viewModels, function(item) { var key; data = item.data; if (data && Ext.isObject(data)) { for (key in data) { isDirect = data.hasOwnProperty(key); if (!dataMap[key]) { dataMap[key] = { isDirect: isDirect }; } dataMap[key].ownerVMs = dataMap[key].ownerVMs || []; if (isDirect) { dataMap[key].ownerVMs.push(item); } } } }); } return vm; } }); Ext.define('Ext.util.ComponentDragger', { extend: 'Ext.dd.DragTracker', autoStart: 500, constructor: function(comp, config) { this.comp = comp; this.initialConstrainTo = config.constrainTo; this.callParent([ config ]); }, onStart: function(e) { var me = this, comp = me.comp; me.startPosition = comp.getXY(); if (comp.ghost && !comp.liveDrag) { me.proxy = comp.ghost(); me.dragTarget = me.proxy.header.el; } if (me.constrain || me.constrainDelegate) { me.constrainTo = me.calculateConstrainRegion(); } if (comp.beginDrag) { comp.beginDrag(); } }, calculateConstrainRegion: function() { var me = this, comp = me.comp, constrainTo = me.initialConstrainTo, constraintInsets = comp.constraintInsets, constrainEl, delegateRegion, elRegion, dragEl = me.proxy ? me.proxy.el : comp.el, shadow = dragEl.shadow, shadowSize = (shadow && !me.constrainDelegate && comp.constrainShadow && !shadow.disabled) ? shadow.getShadowSize() : 0; if (!(constrainTo instanceof Ext.util.Region)) { constrainEl = Ext.fly(constrainTo); constrainTo = constrainEl.getConstrainRegion(); } else { constrainTo = constrainTo.copy(); } if (constraintInsets) { constraintInsets = Ext.isObject(constraintInsets) ? constraintInsets : Ext.Element.parseBox(constraintInsets); constrainTo.adjust(constraintInsets.top, constraintInsets.right, constraintInsets.bottom, constraintInsets.length); } if (shadowSize) { constrainTo.adjust(shadowSize[0], -shadowSize[1], -shadowSize[2], shadowSize[3]); } if (!me.constrainDelegate) { delegateRegion = Ext.fly(me.dragTarget).getRegion(); elRegion = dragEl.getRegion(); constrainTo.adjust(delegateRegion.top - elRegion.top, delegateRegion.right - elRegion.right, delegateRegion.bottom - elRegion.bottom, delegateRegion.left - elRegion.left); } return constrainTo; }, 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.setPagePosition(me.startPosition[0] + offset[0], me.startPosition[1] + offset[1]); }, onEnd: function(e) { var comp = this.comp; if (comp.isDestroyed || comp.destroying) { return; } if (this.proxy && !comp.liveDrag) { comp.unghost(); } if (comp.endDrag) { comp.endDrag(); } } }); Ext.define('Ext.window.Window', { extend: 'Ext.panel.Panel', alternateClassName: 'Ext.Window', requires: [ 'Ext.util.ComponentDragger', 'Ext.util.Region' ], alias: 'widget.window', baseCls: Ext.baseCSSPrefix + 'window', resizable: true, draggable: true, constrain: false, constrainHeader: false, plain: false, minimizable: false, maximizable: false, minHeight: 50, minWidth: 50, expandOnShow: true, collapsible: false, closable: true, hidden: true, autoRender: true, hideMode: 'offsets', floating: true, itemCls: Ext.baseCSSPrefix + 'window-item', overlapHeader: true, ignoreHeaderBorderManagement: true, alwaysFramed: true, isRootCfg: { isRoot: true }, isWindow: true, ariaRole: 'dialog', initComponent: function() { var me = this; me.frame = false; me.callParent(); if (me.plain) { me.addClsWithUI('plain'); } me.addStateEvents([ 'maximize', 'restore', 'resize', 'dragend' ]); }, getElConfig: function() { var me = this, elConfig; elConfig = me.callParent(); elConfig.tabIndex = -1; return elConfig; }, getFocusEl: function() { var me = this; return Ext.enableFocusManager ? me.el : (me.getDefaultFocus() || me.el); }, getState: function() { var me = this, state = me.callParent() || {}, maximized = !!me.maximized, ghostBox = me.ghostBox, pos; state.maximized = maximized; if (maximized) { pos = me.restorePos; } else if (ghostBox) { pos = [ ghostBox.x, ghostBox.y ]; } else { pos = me.getPosition(); } Ext.apply(state, { size: maximized ? me.restoreSize : me.getSize(), pos: pos }); return state; }, 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] }); } } }, onRender: function(ct, position) { var me = this; me.callParent(arguments); if (me.header) { me.header.on({ scope: me, click: me.onHeaderClick }); } if (me.maximizable) { me.header.on({ scope: me, dblclick: me.toggleMaximize }); } }, afterRender: function() { var me = this, header = me.header, keyMap; if (me.maximized) { me.maximized = false; me.maximize(); if (header) { header.removeCls(header.indicateDragCls); } } me.callParent(); if (me.closable) { keyMap = me.getKeyMap(); keyMap.on(27, me.onEsc, me); } else { keyMap = me.keyMap; } if (keyMap && me.hidden) { keyMap.disable(); } }, onEsc: function(k, e) { var mgr = Ext['FocusManager']; if (!Ext.enableFocusManager || mgr.focusedCmp === this) { e.stopEvent(); this.close(); } }, beforeDestroy: function() { var me = this; if (me.rendered) { Ext.un('resize', me.onWindowResize, me); delete me.animateTarget; me.hide(); Ext.destroy(me.keyMap); } me.callParent(); }, addTools: function() { var me = this, tools = []; me.callParent(); if (me.minimizable) { tools.push({ type: 'minimize', handler: 'minimize', scope: me }); } if (me.maximizable) { tools.push({ type: me.maximized ? 'restore' : 'maximize', handler: 'toggleMaximize', scope: me }); } if (tools.length) { me.addTool(tools); } }, onShow: function() { var me = this; me.callParent(arguments); if (me.expandOnShow) { me.expand(false); } me.syncMonitorWindowResize(); if (me.keyMap) { me.keyMap.enable(); } }, doClose: function() { var me = this; if (me.hidden) { me.fireEvent('close', me); if (me.closeAction === 'destroy') { me.destroy(); } } else { me.hide(me.animateTarget, me.doClose, me); } }, afterHide: function() { var me = this; me.syncMonitorWindowResize(); if (me.keyMap) { me.keyMap.disable(); } me.callParent(arguments); }, onWindowResize: function() { var me = this, sizeModel; if (!me.isDestroyed) { if (me.maximized) { me.fitContainer(); } else { sizeModel = me.getSizeModel(); if (sizeModel.width.natural || sizeModel.height.natural) { me.updateLayout(); } me.doConstrain(); } } }, minimize: function() { this.fireEvent('minimize', this); return this; }, resumeHeaderLayout: function(changed) { this.header.resumeLayouts(changed ? this.isRootCfg : null); }, afterCollapse: function() { var me = this, header = me.header, tools = me.tools; if (header && me.maximizable) { header.suspendLayouts(); tools.maximize.hide(); this.resumeHeaderLayout(true); } if (me.resizer) { me.resizer.disable(); } me.callParent(arguments); }, afterExpand: function() { var me = this, header = me.header, tools = me.tools, changed; if (header) { header.suspendLayouts(); if (me.maximizable) { tools.maximize.show(); changed = true; } this.resumeHeaderLayout(changed); } if (me.resizer) { me.resizer.enable(); } me.callParent(arguments); }, maximize: function(animate) { var me = this, header = me.header, tools = me.tools, width = me.width, height = me.height, restore, changed; if (!me.maximized) { me.expand(false); if (!me.hasSavedRestore) { restore = me.restoreSize = { width: width ? width : null, height: height ? height : null }; me.restorePos = me.getPosition(); } if (header) { header.suspendLayouts(); if (tools.maximize) { tools.maximize.setType('restore'); } if (me.collapseTool) { me.collapseTool.hide(); changed = true; } me.resumeHeaderLayout(changed); } me.el.disableShadow(); if (me.dd) { me.dd.disable(); if (header) { header.removeCls(header.indicateDragCls); } } if (me.resizer) { me.resizer.disable(); } me.el.addCls(Ext.baseCSSPrefix + 'window-maximized'); me.container.addCls(Ext.baseCSSPrefix + 'window-maximized-ct'); me.syncMonitorWindowResize(); me.fitContainer(animate = (animate || !!me.animateTarget) ? { callback: function() { me.maximized = true; me.fireEvent('maximize', me); } } : null); if (!animate) { me.maximized = true; me.fireEvent('maximize', me); } } return me; }, restore: function(animate) { var me = this, tools = me.tools, header = me.header, newBox = me.restoreSize, changed; if (me.maximized) { me.hasSavedRestore = null; me.removeCls(Ext.baseCSSPrefix + 'window-maximized'); if (header) { header.suspendLayouts(); if (tools.maximize) { tools.maximize.setType('maximize'); } if (me.collapseTool) { me.collapseTool.show(); changed = true; } me.resumeHeaderLayout(changed); } newBox.x = me.restorePos[0]; newBox.y = me.restorePos[1]; me.setBox(newBox, animate = (animate || !!me.animateTarget) ? { callback: function() { me.el.enableShadow(null, true); me.maximized = false; me.fireEvent('restore', me); } } : null); me.restorePos = me.restoreSize = null; if (me.dd) { me.dd.enable(); if (header) { header.addCls(header.indicateDragCls); } } if (me.resizer) { me.resizer.enable(); } me.container.removeCls(Ext.baseCSSPrefix + 'window-maximized-ct'); me.syncMonitorWindowResize(); if (!animate) { me.el.enableShadow(null, true); me.maximized = false; me.fireEvent('restore', me); } } return me; }, syncMonitorWindowResize: function() { var me = this, currentlyMonitoring = me._monitoringResize, yes = me.monitorResize || me.constrain || me.constrainHeader || me.maximized, veto = me.hidden || me.destroying || me.isDestroyed; if (yes && !veto) { if (!currentlyMonitoring) { Ext.on('resize', me.onWindowResize, me, { buffer: 1 }); me._monitoringResize = true; } } else if (currentlyMonitoring) { Ext.un('resize', me.onWindowResize, me); me._monitoringResize = false; } }, toggleMaximize: function() { return this[this.maximized ? 'restore' : 'maximize'](); }, createGhost: function() { var ghost = this.callParent(arguments); ghost.xtype = 'window'; return ghost; }, getDefaultFocus: function() { var me = this, result, defaultComp = me.defaultButton || me.defaultFocus, selector; if (defaultComp !== undefined) { if (Ext.isNumber(defaultComp)) { result = me.query('button')[defaultComp]; } else if (Ext.isString(defaultComp)) { selector = defaultComp; if (Ext.validIdRe.test(selector)) { result = me.down(Ext.makeIdSelector(selector)); } if (!result) { result = me.down(selector); } } else if (defaultComp.focus) { result = defaultComp; } } return result; }, privates: { initDraggable: function() { this.initSimpleDraggable(); }, onHeaderClick: function(header, e) { var delegate; if (header.el.contains(e.getTarget())) { delegate = this.getDefaultFocus(); if (delegate) { delegate.focus(); } } }, initResizable: function() { this.callParent(arguments); if (this.maximized) { this.resizer.disable(); } } } }); Ext.define('Ext.tip.Tip', { extend: 'Ext.panel.Panel', alias: 'widget.tip', alternateClassName: 'Ext.Tip', minWidth: 40, maxWidth: 500, shadow: "sides", defaultAlign: "tl-bl?", constrainPosition: true, autoRender: true, hidden: true, baseCls: Ext.baseCSSPrefix + 'tip', focusOnToFront: false, closeAction: 'hide', alwaysFramed: true, frameHeader: false, initComponent: function() { var me = this; me.floating = Ext.apply({}, { shadow: me.shadow, constrain: me.constrainPosition }, me.self.prototype.floating); me.callParent(arguments); me.constrain = me.constrain || me.constrainPosition; }, showAt: function(xy) { var me = this; this.callParent(arguments); if (me.isVisible()) { me.setPagePosition(xy[0], xy[1]); if (me.constrainPosition || me.constrain) { me.doConstrain(); } me.toFront(true); } }, privates: { initDraggable: function() { var me = this; me.draggable = { el: me.getDragEl(), delegate: me.header.el, constrain: me, constrainTo: me.el.dom.parentNode }; 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', autoHide: true, showDelay: 500, hideDelay: 200, dismissDelay: 5000, trackMouse: false, anchorToTarget: true, anchorOffset: 0, targetCounter: 0, quickShowInterval: 250, hideAction: 'hide', fadeOutDuration: 1000, ariaRole: 'tooltip', 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(); if (me.sticky) { me.el.dom.setAttribute('data-sticky', true); } me.anchorEl = me.el.createChild({ role: 'presentation', cls: Ext.baseCSSPrefix + 'tip-anchor ' + me.anchorCls }); }, setTarget: function(target) { var me = this, t = Ext.get(target), tg; if (me.target) { tg = Ext.get(me.target); if (Ext.supports.Touch) { me.mun(tg, 'tap', me.onTargetOver, me); } else { me.mun(tg, { mouseover: me.onTargetOver, mouseout: me.onTargetOut, mousemove: me.onMouseMove, scope: me }); } } me.target = t; if (t) { if (Ext.supports.Touch) { me.mon(t, { tap: me.onTargetOver, scope: me }); } else { me.mon(t, { 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, xy; if (!me.target || me.target.contains(e.target)) { t = me.delegate ? e.getTarget(me.delegate) : (me.triggerElement = true); 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.parent()); } me.setPagePosition(xy); } } else { me.hide(); me.lastActive = new Date(0); me.onTargetOver(e); } } else if ((!me.closable && me.isVisible()) && me.autoHide !== false) { me.delayHide(); } } }, getTargetXY: function() { var me = this, mouseOffset, offsets, xy, dw, dh, de, bd, scrollX, scrollY, axy, sz, constrainPosition; if (me.delegate) { me.anchorTarget = me.triggerElement; } if (me.anchor) { me.targetCounter++; offsets = me.getOffsets(); xy = (me.anchorToTarget && !me.trackMouse) ? me.getAlignToXY(me.anchorTarget, me.getAnchorAlign()) : me.targetXY; dw = Ext.Element.getViewportWidth() - 5; dh = Ext.Element.getViewportHeight() - 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; } }, calculateConstrainedPosition: function(constrainTo) { var me = this, visible, result, floatParentBox; if (!constrainTo && me.isContainedFloater()) { visible = me.isVisible(); if (!visible) { me.el.show(); } result = me.getTargetXY(); if (!visible) { me.el.hide(); } floatParentBox = me.floatParent.getTargetEl().getViewRegion(); result[0] -= floatParentBox.left; result[1] -= floatParentBox.top; } else { result = me.callOverridden(arguments); } return result; }, 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; }, fadeOut: function() { var me = this; me.el.fadeOut({ duration: me.fadeOutDuration, callback: function() { me.hide(); me.el.setOpacity(''); } }); }, 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, delegate = me.delegate, t; if (me.disabled || e.within(me.target.dom, true)) { return; } t = delegate ? e.getTarget(delegate) : true; if (t) { me.triggerElement = t; me.triggerEvent = e; me.clearTimer('hide'); me.targetXY = e.getXY(); me.delayShow(); } }, delayShow: function(trackMouse) { var me = this, xy = me.el && (trackMouse === false || !me.trackMouse) && me.getTargetXY(); if (me.hidden && !me.showTimer) { if (Ext.Date.getElapsed(me.lastActive) < me.quickShowInterval) { me.show(); } else { me.showTimer = Ext.defer(me.showFromDelay, me.showDelay, me, [ xy ]); } } else if (!me.hidden && me.autoHide !== false) { me.show(xy); } }, showFromDelay: function(xy) { var me = this; if (me.disabled) { return; } me.fromDelayShow = true; me.show(xy); delete me.fromDelayShow; }, onShowVeto: function() { this.callParent(); delete this.triggerElement; this.clearTimer('show'); }, onTargetOut: function(e) { var me = this, triggerEl = me.triggerElement, target = triggerEl === true ? me.target : triggerEl; if (me.disabled || !triggerEl || e.within(target, true)) { return; } if (me.showTimer) { me.clearTimer('show'); me.triggerElement = null; } if (me.autoHide !== false) { me.delayHide(); } }, delayHide: function() { var me = this; if (!me.hidden && !me.hideTimer) { me.hideTimer = Ext.defer(me[me.hideAction], 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(xy) { var me = this; this.callParent(); if (this.hidden === false) { if (me.anchor) { me.anchor = me.origAnchor; } if (!me.calledFromShowAt) { me.showAt(xy || me.getTargetXY()); } } }, showAt: function(xy) { var me = this; me.lastActive = new Date(); me.clearTimers(); me.calledFromShowAt = true; if (!me.isVisible()) { this.callParent(arguments); } if (me.isVisible()) { me.setPagePosition(xy[0], xy[1]); if (me.constrainPosition || me.constrain) { me.doConstrain(); } me.toFront(true); me.el.syncUnderlays(); if (me.dismissDelay && me.autoHide !== false) { me.dismissTimer = Ext.defer(me.hide, me.dismissDelay, me); } } delete me.calledFromShowAt; }, 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); me.anchorEl.setStyle('z-index', parseInt(me.el.getZIndex(), 10) || 0 + 1).setVisibilityMode(Ext.Element.DISPLAY); }, afterSetPosition: function(x, y) { var me = this; me.callParent(arguments); if (me.anchor) { me.syncAnchor(); if (!me.anchorEl.isVisible()) { me.anchorEl.show(); } } else { me.anchorEl.hide(); } }, _timerNames: {}, clearTimer: function(name) { var me = this, names = me._timerNames, propName = names[name] || (names[name] = name + 'Timer'), timer = me[propName]; if (timer) { clearTimeout(timer); me[propName] = null; } }, 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.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', alias: 'widget.quicktip', 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', showDelay: 'qshowDelay', hideAction: 'hideAction', anchorTarget: 'anchorTarget' }, shrinkWrapDock: true, initComponent: function() { var me = this; me.target = me.target || Ext.getDoc(); me.targets = me.targets || {}; me.callParent(); }, setTagConfig: function(cfg) { this.tagConfig = Ext.apply({}, cfg); delete this.tagConfig.attr; }, text: null, 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; 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(target, event) { var titleText = target.title, cfg = this.tagConfig, attr = cfg.attr || (cfg.attr = cfg.namespace + cfg.attribute), text; if (this.interceptTitles && titleText && Ext.isString(titleText)) { target.setAttribute(attr, titleText); target.removeAttribute('title'); return { text: titleText }; } else { target = Ext.fly(target).findParent(function(dom) { return (text = dom.getAttribute(attr)); }); if (target) { return { target: target, text: text }; } } }, onTargetOver: function(event) { this.doTargetOver(event.getTarget(this.delegate), null, event); }, doTargetOver: function(target, xy, event) { var me = this, hasShowDelay, hideAction, delay, elTarget, cfg, ns, tipConfig, autoHide, targets, targetEl, value, key; if (me.disabled) { return; } if (typeof target === 'string') { target = Ext.getDom(target); } me.targetXY = xy || (event ? event.getXY() : Ext.fly(target).getXY()); if (!target || target.nodeType !== 1 || target === document.documentElement || target === document.body) { return; } if (me.activeTarget && ((target === me.activeTarget.el) || Ext.fly(me.activeTarget.el).contains(target))) { if (me.targetTextEmpty()) { me.onShowVeto(); delete me.activeTarget; } else { me.clearTimer('hide'); me.show(); } return; } if (target) { targets = me.targets; for (key in targets) { if (targets.hasOwnProperty(key)) { value = targets[key]; targetEl = Ext.fly(value.target); if (targetEl && (targetEl.dom === target || targetEl.contains(target))) { elTarget = targetEl.dom; break; } } } if (elTarget) { me.activeTarget = me.targets[elTarget.id]; me.activeTarget.el = target; me.anchor = me.activeTarget.anchor; if (me.anchor) { me.anchorTarget = target; } hasShowDelay = parseInt(me.activeTarget.showDelay, 10); if (hasShowDelay) { delay = me.showDelay; me.showDelay = hasShowDelay; } me.delayShow(); if (hasShowDelay) { me.showDelay = delay; } if (!(hideAction = me.activeTarget.hideAction)) { delete me.hideAction; } else { me.hideAction = hideAction; } return; } } elTarget = Ext.fly(target, '_quicktip-target'); cfg = me.tagConfig; ns = cfg.namespace; tipConfig = me.getTipCfg(target, event); if (tipConfig) { if (tipConfig.target) { target = tipConfig.target; elTarget = Ext.fly(target, '_quicktip-target'); } autoHide = elTarget.getAttribute(ns + cfg.hide); me.activeTarget = { el: target, text: tipConfig.text, width: +elTarget.getAttribute(ns + cfg.width) || null, autoHide: autoHide !== "user" && autoHide !== 'false', title: elTarget.getAttribute(ns + cfg.title), cls: elTarget.getAttribute(ns + cfg.cls), align: elTarget.getAttribute(ns + cfg.align), showDelay: parseInt(elTarget.getAttribute(ns + cfg.showDelay) || 0, 10), hideAction: elTarget.getAttribute(ns + cfg.hideAction), anchorTarget: elTarget.getAttribute(ns + cfg.anchorTarget) }; if (!me.initialConfig.hasOwnProperty('anchor')) { me.anchor = elTarget.getAttribute(ns + cfg.anchor); } if (me.anchor && !me.initialConfig.hasOwnProperty('anchorTarget')) { me.anchorTarget = me.activeTarget.anchorTarget || target; } hasShowDelay = parseInt(me.activeTarget.showDelay, 10); if (hasShowDelay) { delay = me.showDelay; me.showDelay = hasShowDelay; } me.delayShow(); if (hasShowDelay) { me.showDelay = delay; } } }, onTargetOut: function(e) { var me = this, active = me.activeTarget, hasHideDelay, delay; if (active && e.within(me.activeTarget.el) && !me.getTipCfg(e.getTarget(), e)) { return; } me.clearTimer('show'); delete me.activeTarget; if (me.autoHide !== false) { hasHideDelay = active && parseInt(active.hideDelay, 10); if (hasHideDelay) { delay = me.hideDelay; me.hideDelay = hasHideDelay; } me.delayHide(); if (hasHideDelay) { me.hideDelay = delay; } } }, targetTextEmpty: function() { var me = this, target = me.activeTarget, cfg = me.tagConfig, el, text; if (target) { el = target.el; if (el) { text = el.getAttribute(cfg.namespace + cfg.attribute); if (!text && !me.targets[Ext.id(target.target)]) { return true; } } } return false; }, show: function() { var me = this, fromDelay = me.fromDelayShow; if (fromDelay && me.targetTextEmpty()) { me.onShowVeto(); delete me.activeTarget; return; } me.callParent(arguments); }, showAt: function(xy) { var me = this, target = me.activeTarget, header = me.header, dismiss, cls; if (target) { if (!me.rendered) { me.render(Ext.getBody()); me.activeTarget = target; } me.suspendLayouts(); if (target.title) { me.setTitle(target.title); header.show(); } else if (header) { header.hide(); } me.update(target.text); me.autoHide = target.autoHide; dismiss = target.dismissDelay; me.dismissDelay = Ext.isNumber(dismiss) ? dismiss : me.dismissDelay; if (target.mouseOffset) { xy[0] += target.mouseOffset[0]; xy[1] += target.mouseOffset[1]; } cls = me.lastCls; if (cls) { me.removeCls(cls); delete me.lastCls; } cls = target.cls; if (cls) { me.addCls(cls); me.lastCls = cls; } me.setWidth(target.width); if (me.anchor) { me.constrainPosition = false; } else if (target.align) { xy = me.getAlignToXY(target.el, target.align); me.constrainPosition = false; } else { me.constrainPosition = true; } me.resumeLayouts(true); } me.callParent([ xy ]); }, hide: function() { delete this.activeTarget; this.callParent(); } }); Ext.define('Ext.tip.QuickTipManager', { requires: [ 'Ext.tip.QuickTip' ], singleton: true, alternateClassName: 'Ext.QuickTips', disabled: false, init: function(autoRender, config) { var me = this; if (!me.tip) { if (!Ext.isReady) { Ext.onInternalReady(function() { Ext.tip.QuickTipManager.init(autoRender, config); }); return false; } var tipConfig = Ext.apply({ sticky: true, disabled: me.disabled, id: 'ext-quicktips-tip' }, config), className = tipConfig.className, xtype = tipConfig.xtype; if (className) { delete tipConfig.className; } else if (xtype) { className = 'widget.' + xtype; delete tipConfig.xtype; } if (autoRender !== false) { tipConfig.renderTo = document.body; if (tipConfig.renderTo.tagName.toUpperCase() !== 'BODY') { Ext.Error.raise({ sourceClass: 'Ext.tip.QuickTipManager', sourceMethod: 'init', msg: 'Cannot init QuickTipManager: no document body' }); } } me.tip = Ext.create(className || 'Ext.tip.QuickTip', tipConfig); Ext.quickTipsActive = true; } }, destroy: function() { Ext.destroy(this.tip); this.tip = undefined; }, ddDisable: function() { var me = this, tip = me.tip; if (tip && !me.disabled) { tip.disable(); } }, ddEnable: function() { var me = this, tip = me.tip; if (tip && !me.disabled) { tip.enable(); } }, enable: function() { var me = this, tip = me.tip; if (tip) { tip.enable(); } me.disabled = false; }, disable: function() { var me = this, tip = me.tip; if (tip) { tip.disable(); } me.disabled = true; }, isEnabled: function() { var tip = this.tip; return tip !== undefined && !tip.disabled; }, getQuickTip: function() { return this.tip; }, register: function() { var tip = this.tip; tip.register.apply(tip, arguments); }, unregister: function() { var tip = this.tip; tip.unregister.apply(tip, arguments); }, tips: function() { var tip = this.tip; tip.register.apply(tip, arguments); } }); Ext.define('Ext.app.bindinspector.Inspector', { extend: 'Ext.window.Window', requires: [ 'Ext.app.bindinspector.Container', 'Ext.layout.container.Fit', 'Ext.tip.QuickTipManager' ], title: 'Bind Inspector', layout: 'fit', autoShow: true, maximized: true, maximizable: true, width: 960, height: 575, initComponent: function() { var snapshot = (new Ext.app.bindinspector.Environment()).captureSnapshot(), env = new Ext.app.bindinspector.Environment(); env.unpackSnapshot(snapshot); this.items = { xtype: 'bindinspector-container', env: env }; this.callParent(); }, afterRender: function() { this.callParent(arguments); Ext.tip.QuickTipManager.init(); } }); Ext.define('Ext.button.Split', { alias: 'widget.splitbutton', extend: 'Ext.button.Button', alternateClassName: 'Ext.SplitButton', isSplitButton: true, arrowCls: 'split', split: true, setArrowHandler: function(handler, scope) { this.arrowHandler = handler; this.scope = scope; }, onClick: function(e) { var me = this; me.doPreventDefault(e); if (!me.disabled) { if (me.isWithinTrigger(e)) { e.preventDefault(); me.maybeShowMenu(e); me.fireEvent("arrowclick", me, e); if (me.arrowHandler) { me.arrowHandler.call(me.scope || me, me, e); } } else { me.doToggle(); me.fireHandler(e); } } } }); Ext.define('Ext.button.Cycle', { alias: 'widget.cycle', extend: 'Ext.button.Split', alternateClassName: 'Ext.CycleButton', getButtonText: function(item) { var me = this, text = ''; if (item && me.showText === true) { if (me.prependText) { text += me.prependText; } text += item.text; return text; } return me.text; }, setActiveItem: function(item, suppressEvent) { var me = this, changeHandler = me.changeHandler, forceIcon = me.forceIcon, forceGlyph = me.forceGlyph; me.settingActive = true; if (!Ext.isObject(item)) { item = me.menu.getComponent(item); } if (item) { me.setText(me.getButtonText(item)); me.setIconCls(forceIcon ? forceIcon : item.iconCls); me.setGlyph(forceGlyph ? forceGlyph : item.glyph); me.activeItem = item; if (!item.checked) { item.setChecked(true, false); } if (!suppressEvent) { if (changeHandler) { Ext.callback(changeHandler, me.scope, [ me, item ], 0, me); } me.fireEvent('change', me, item); } } me.settingActive = false; }, getActiveItem: function() { return this.activeItem; }, initComponent: function() { var me = this, checked = 0, items, i, iLen, item; items = (me.menu.items || []).concat(me.items || []); me.menu = Ext.applyIf({ cls: Ext.baseCSSPrefix + 'cycle-menu', items: [] }, me.menu); iLen = items.length; for (i = 0; i < iLen; i++) { item = items[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, true); }, checkHandler: function(item, pressed) { if (pressed && !this.settingActive) { this.setActiveItem(item); } }, 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.button.Segmented', { extend: 'Ext.container.Container', xtype: 'segmentedbutton', requires: [ 'Ext.button.Button' ], config: { allowDepress: false, allowMultiple: false, allowToggle: true, vertical: false, defaultUI: 'default' }, beforeRenderConfig: { value: undefined }, defaultBindProperty: 'value', publishes: [ 'value' ], twoWayBindable: [ 'value' ], layout: 'segmentedbutton', defaultType: 'button', maskOnDisable: false, isSegmentedButton: true, baseCls: Ext.baseCSSPrefix + 'segmented-button', itemCls: Ext.baseCSSPrefix + 'segmented-button-item', _firstCls: Ext.baseCSSPrefix + 'segmented-button-first', _lastCls: Ext.baseCSSPrefix + 'segmented-button-last', _middleCls: Ext.baseCSSPrefix + 'segmented-button-middle', applyValue: function(value, oldValue) { var me = this, allowMultiple = me.getAllowMultiple(), buttonValue, button, values, oldValues, items, i, ln; values = (value instanceof Array) ? value : (value == null) ? [] : [ value ]; oldValues = (oldValue instanceof Array) ? oldValue : (oldValue == null) ? [] : [ oldValue ]; me._isApplyingValue = true; if (!me.rendered) { items = me.items.items; for (i = 0 , ln = items.length; i < ln; i++) { button = items[i]; if (button.pressed) { buttonValue = button.value; if (buttonValue == null) { buttonValue = me.items.indexOf(button); } if (!Ext.Array.contains(values, buttonValue)) { values.push(buttonValue); } } } } ln = values.length; if (ln > 1 && !allowMultiple) { Ext.Error.raise('Cannot set multiple values when allowMultiple is false'); } for (i = 0; i < ln; i++) { value = values[i]; button = me._lookupButtonByValue(value); if (button) { buttonValue = button.value; if ((buttonValue != null) && buttonValue !== value) { values[i] = buttonValue; } if (!button.pressed) { button.setPressed(true); } } else { Ext.Error.raise("Invalid value '" + value + "' for segmented button: '" + me.id + "'"); } } value = allowMultiple ? values : ln ? values[0] : null; for (i = 0 , ln = oldValues.length; i < ln; i++) { oldValue = oldValues[i]; if (!Ext.Array.contains(values, oldValue)) { me._lookupButtonByValue(oldValue).setPressed(false); } } me._isApplyingValue = false; return value; }, beforeRender: function() { var me = this; me.addCls(me.baseCls + me._getClsSuffix()); me._syncItemClasses(true); me.callParent(); }, onAdd: function(item) { var me = this, syncItemClasses = '_syncItemClasses'; var items = me.items.items, ln = items.length, i = 0, value, defaultUI; if (item.ui === 'default' && !item.hasOwnProperty('ui')) { defaultUI = me.getDefaultUI(); if (defaultUI !== 'default') { item.ui = defaultUI; } } for (; i < ln; i++) { if (items[i] !== item) { value = items[i].value; if (value != null && value === item.value) { Ext.Error.raise("Segmented button '" + me.id + "' cannot contain multiple items with value: '" + value + "'"); } } } me.mon(item, { hide: syncItemClasses, show: syncItemClasses, toggle: '_onItemToggle', scope: me }); if (me.getAllowToggle()) { item.enableToggle = true; if (!me.getAllowMultiple()) { item.toggleGroup = me.getId(); item.allowDepress = me.getAllowDepress(); } } item.addCls(me.itemCls + me._getClsSuffix()); me._syncItemClasses(); me.callParent([ item ]); }, onRemove: function(item) { var me = this; item.removeCls(me.itemCls + me._getClsSuffix()); me._syncItemClasses(); me.callParent([ item ]); }, beforeLayout: function() { if (Ext.isChrome) { this.el.dom.offsetWidth; } this.callParent(); }, updateDefaultUI: function(defaultUI) { var items = this.items, item, i, ln; if (this.rendered) { Ext.Error.raise("Changing the ui config of a segmented button after render is not supported."); } else if (items) { if (items.items) { items = items.items; } for (i = 0 , ln = items.length; i < ln; i++) { item = items[i]; if (item.ui === 'default' && defaultUI !== 'default' && !item.hasOwnProperty('ui')) { items[i].ui = defaultUI; } } } }, updateAllowDepress: function(newAllowDepress, oldAllowDepress) { if (this.rendered && (newAllowDepress !== oldAllowDepress)) { Ext.Error.raise("Changing the allowDepress config of a segmented button after render is not supported."); } }, updateAllowMultiple: function(newAllowMultiple, oldAllowMultiple) { if (this.rendered && (newAllowMultiple !== oldAllowMultiple)) { Ext.Error.raise("Changing the allowMultiple config of a segmented button after render is not supported."); } }, updateAllowToggle: function(newAllowToggle, oldAllowToggle) { if (this.rendered && (newAllowToggle !== oldAllowToggle)) { Ext.Error.raise("Changing the allowToggle config of a segmented button after render is not supported."); } }, updateVertical: function(newVertical, oldVertical) { if (this.rendered && (newVertical !== oldVertical)) { Ext.Error.raise("Changing the orientation of a segmented button after render is not supported."); } }, privates: { _getClsSuffix: function() { return this.getVertical() ? '-vertical' : '-horizontal'; }, _getFirstCls: function() { return this._firstCls; }, _getLastCls: function() { return this._lastCls; }, _lookupButtonByValue: function(value) { var items = this.items.items, ln = items.length, i = 0, button = null, buttonValue, btn; for (; i < ln; i++) { btn = items[i]; buttonValue = btn.value; if ((buttonValue != null) && buttonValue === value) { button = btn; break; } } if (!button && typeof value === 'number') { button = items[value]; } return button; }, _onItemToggle: function(button, pressed) { if (this._isApplyingValue) { return; } var me = this, Array = Ext.Array, allowMultiple = me.allowMultiple, buttonValue = (button.value != null) ? button.value : me.items.indexOf(button), value = me.getValue(), valueIndex; if (allowMultiple) { valueIndex = Array.indexOf(value, buttonValue); } if (pressed) { if (allowMultiple) { if (valueIndex === -1) { value.push(buttonValue); } } else { value = buttonValue; } } else { if (allowMultiple) { if (valueIndex > -1) { value.splice(valueIndex, 1); } } else if (value === buttonValue) { value = null; } } me.setValue(value); me.fireEvent('toggle', me, button, pressed); }, _syncItemClasses: function(force) { var me = this, firstCls, middleCls, lastCls, items, ln, visibleItems, item, i; if (!force && !me.rendered) { return; } firstCls = me._getFirstCls(); middleCls = me._middleCls; lastCls = me._getLastCls(); items = me.items.items; ln = items.length; visibleItems = []; for (i = 0; i < ln; i++) { item = items[i]; if (!item.hidden) { visibleItems.push(item); } } ln = visibleItems.length; for (i = 0; i < ln; i++) { visibleItems[i].removeCls([ firstCls, middleCls, lastCls ]); } if (ln > 1) { visibleItems[0].addCls(firstCls); for (i = 1; i < ln - 1; i++) { visibleItems[i].addCls(middleCls); } visibleItems[ln - 1].addCls(lastCls); } } } }); Ext.define('Ext.layout.container.Table', { alias: [ 'layout.table' ], extend: 'Ext.layout.container.Container', alternateClassName: 'Ext.layout.TableLayout', type: 'table', createsInnerCt: true, targetCls: Ext.baseCSSPrefix + 'table-layout-ct', tableCls: Ext.baseCSSPrefix + 'table-layout', cellCls: Ext.baseCSSPrefix + 'table-layout-cell', childEls: [ 'table', 'tbody' ], tableAttrs: null, getItemSizePolicy: function(item) { return this.autoSizePolicy; }, initInheritedState: function(inheritedState, inheritedStateInner) { inheritedStateInner.inShrinkWrapTable = true; }, getLayoutItems: function() { var me = this, result = [], items = me.callParent(), item, len = items.length, i; for (i = 0; i < len; i++) { item = items[i]; if (!item.hidden) { result.push(item); } } return result; }, getHiddenItems: function() { var result = [], items = this.owner.items.items, len = items.length, i = 0, item; for (; i < len; ++i) { item = items[i]; if (item.rendered && item.hidden) { result.push(item); } } return result; }, renderChildren: function() { var me = this, items = me.getLayoutItems(), tbody = me.tbody.dom, rows = tbody.rows, len = items.length, hiddenItems = me.getHiddenItems(), cells, curCell, rowIdx, cellIdx, item, trEl, tdEl, i, cellId, oldId; cells = me.calculateCells(items); for (i = 0; i < len; i++) { curCell = cells[i]; rowIdx = curCell.rowIdx; cellIdx = curCell.cellIdx; item = items[i]; cellId = item.cellId || ''; trEl = rows[rowIdx]; if (!trEl) { trEl = tbody.insertRow(rowIdx); if (me.trAttrs) { trEl.set(me.trAttrs); } } tdEl = Ext.get(trEl.cells[cellIdx] || trEl.insertCell(cellIdx)); if (!item.rendered) { me.renderItem(item, tdEl, 0); } else if (!me.isValidParent(item, tdEl, rowIdx, cellIdx, tbody)) { me.moveItem(item, tdEl, 0); } if (me.tdAttrs) { tdEl.set(me.tdAttrs); } if (item.tdAttrs) { tdEl.set(item.tdAttrs); } oldId = tdEl.getAttribute('data-cellId'); if ((oldId || cellId) && oldId !== cellId) { tdEl.setId(cellId || Ext.id()); } tdEl.set({ colSpan: item.colspan || 1, rowSpan: item.rowspan || 1, 'data-cellId': cellId, cls: me.cellCls + ' ' + (item.cellCls || '') }); if (!cells[i + 1] || cells[i + 1].rowIdx !== rowIdx) { cellIdx++; while (trEl.cells[cellIdx]) { trEl.deleteCell(cellIdx); } } } rowIdx++; while (tbody.rows[rowIdx]) { tbody.deleteRow(rowIdx); } for (i = 0 , len = hiddenItems.length; i < len; ++i) { me.ensureInDocument(hiddenItems[i].getEl()); } }, ensureInDocument: function(el) { var dom = el.dom.parentNode; while (dom) { if (dom.tagName.toUpperCase() === 'BODY') { return; } dom = dom.parentNode; } Ext.getDetachedBody().appendChild(el); }, calculate: function(ownerContext) { if (!ownerContext.hasDomProp('containerChildrenSizeDone')) { this.done = false; } else { var targetContext = ownerContext.targetContext, widthShrinkWrap = ownerContext.widthModel.shrinkWrap, heightShrinkWrap = ownerContext.heightModel.shrinkWrap, shrinkWrap = heightShrinkWrap || widthShrinkWrap, table = shrinkWrap && this.table.dom, targetPadding = shrinkWrap && targetContext.getPaddingInfo(); if (widthShrinkWrap) { ownerContext.setContentWidth(table.offsetWidth + targetPadding.width, true); } if (heightShrinkWrap) { ownerContext.setContentHeight(table.offsetHeight + targetPadding.height, true); } } }, 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++; } } cells.push({ rowIdx: rowIdx, cellIdx: cellIdx }); for (j = item.colspan || 1; j; --j) { rowspans[colIdx] = item.rowspan || 1; ++colIdx; } ++cellIdx; } return cells; }, getRenderTree: function() { var me = this, items = me.getLayoutItems(), rows = [], result = Ext.apply({ tag: 'table', id: me.owner.id + '-table', "data-ref": 'table', role: 'presentation', cls: me.tableCls, cellspacing: 0, cellpadding: 0, cn: { tag: 'tbody', id: me.owner.id + '-tbody', "data-ref": 'tbody', role: 'presentation', cn: rows } }, me.tableAttrs), tdAttrs = me.tdAttrs, len = items.length, i, cells, item, curCell, tr, rowIdx, cellIdx, cell, cellId, props; cells = me.calculateCells(items); for (i = 0; i < len; i++) { item = items[i]; curCell = cells[i]; rowIdx = curCell.rowIdx; cellIdx = curCell.cellIdx; cellId = item.cellId || ''; tr = rows[rowIdx]; if (!tr) { tr = rows[rowIdx] = { tag: 'tr', role: 'presentation', cn: [] }; if (me.trAttrs) { Ext.apply(tr, me.trAttrs); } } cell = tr.cn[cellIdx] = { tag: 'td', role: 'presentation' }; if (tdAttrs) { Ext.apply(cell, tdAttrs); } props = { colSpan: item.colspan || 1, rowSpan: item.rowspan || 1, 'data-cellId': cellId, cls: me.cellCls + ' ' + (item.cellCls || '') }; if (cellId) { props.id = cellId; } Ext.apply(cell, props); me.configureItem(item); cell.cn = item.getRenderTree(); } return result; }, isValidParent: function(item, target, rowIdx, cellIdx) { if (arguments.length === 3) { return this.table.isAncestor(item.el); } return item.el.dom.parentNode === this.tbody.dom.rows[rowIdx].cells[cellIdx]; } }); Ext.define('Ext.container.ButtonGroup', { extend: 'Ext.panel.Panel', alias: 'widget.buttongroup', alternateClassName: 'Ext.ButtonGroup', requires: [ 'Ext.layout.container.Table' ], baseCls: Ext.baseCSSPrefix + 'btn-group', layout: { type: 'table' }, defaultType: 'button', frame: true, frameHeader: false, titleAlign: 'center', noTitleCls: 'notitle', ariaRole: 'group', initComponent: function() { var me = this, cols = me.columns; if (cols) { me.layout = Ext.apply({}, { columns: cols }, me.layout); } if (!me.title) { me.addClsWithUI(me.noTitleCls); } me.callParent(arguments); }, onBeforeAdd: function(component) { if (component.isButton) { if (this.defaultButtonUI && component.ui === 'default' && !component.hasOwnProperty('ui')) { component.ui = this.defaultButtonUI; } else { component.ui = component.ui + '-toolbar'; } } this.callParent(arguments); }, privates: { applyDefaults: function(c) { if (!Ext.isString(c)) { c = this.callParent(arguments); } return c; } } }); Ext.define('Ext.container.Monitor', { target: null, selector: '', scope: null, addHandler: null, removeHandler: null, invalidateHandler: null, disabled: 0, constructor: function(config) { Ext.apply(this, config); }, bind: function(target) { var me = this; me.target = target; target.on('beforedestroy', me.disable, me); me.onContainerAdd(target); }, unbind: function() { var me = this, target = me.target; if (target) { target.un('beforedestroy', me.disable, me); } me.items = null; }, disable: function() { ++this.disabled; }, enable: function() { if (this.disabled > 0) { --this.disabled; } }, handleAdd: function(ct, comp) { if (!this.disabled) { if (comp.is(this.selector)) { this.onItemAdd(comp.ownerCt, comp); } if (comp.isQueryable) { this.onContainerAdd(comp); } } }, onItemAdd: function(ct, comp) { var me = this, items = me.items, handler = me.addHandler; if (!me.disabled) { if (handler) { handler.call(me.scope || comp, comp); } if (items) { items.add(comp); } } }, onItemRemove: function(ct, comp) { var me = this, items = me.items, handler = me.removeHandler; if (!me.disabled) { if (handler) { handler.call(me.scope || comp, comp); } if (items) { items.remove(comp); } } }, onContainerAdd: function(ct, preventChildren) { var me = this, items, len, handleAdd = me.handleAdd, handleRemove = me.handleRemove, i, comp; if (ct.isContainer) { ct.on('add', handleAdd, me); ct.on('dockedadd', handleAdd, me); ct.on('remove', handleRemove, me); ct.on('dockedremove', handleRemove, me); } if (preventChildren !== true) { items = ct.query(me.selector); for (i = 0 , len = items.length; i < len; ++i) { comp = items[i]; me.onItemAdd(comp.ownerCt, comp); } } items = ct.query('>container'); for (i = 0 , len = items.length; i < len; ++i) { me.onContainerAdd(items[i], true); } }, handleRemove: function(ct, comp) { var me = this; if (!me.disabled) { if (comp.is(me.selector)) { me.onItemRemove(ct, comp); } if (comp.isQueryable) { me.onContainerRemove(ct, comp); } } }, onContainerRemove: function(ct, comp) { var me = this, items, i, len, item; if (!comp.isDestroyed && !comp.destroying && comp.isContainer) { me.removeCtListeners(comp); items = comp.query(me.selector); for (i = 0 , len = items.length; i < len; ++i) { item = items[i]; me.onItemRemove(item.ownerCt, item); } items = comp.query('container'); for (i = 0 , len = items.length; i < len; ++i) { me.removeCtListeners(items[i]); } } else { me.invalidateItems(true); } }, removeCtListeners: function(comp) { var me = this; comp.un('add', me.handleAdd, me); comp.un('dockedadd', me.handleAdd, me); comp.un('remove', me.handleRemove, me); comp.un('dockedremove', me.handleRemove, me); }, getItems: function() { var me = this, items = me.items; if (!items) { items = me.items = new Ext.util.MixedCollection(); items.addAll(me.target.query(me.selector)); } return items; }, invalidateItems: function(triggerHandler) { var me = this, handler = me.invalidateHandler; if (triggerHandler && handler) { handler.call(me.scope || me, me); } me.items = null; } }); Ext.define('Ext.plugin.Responsive', { extend: 'Ext.mixin.Responsive', alias: 'plugin.responsive', pluginId: 'responsive', isPlugin: true, constructor: function(config) { var me = this, cmp = config.cmp, c = Ext.apply({ responsiveConfig: cmp.responsiveConfig, responsiveFormulas: cmp.responsiveFormulas }, config); delete c.cmp; me.cmp = cmp; if (!cmp) { Ext.Error.raise('Responsive plugin must be constructed by Component'); } me.initConfig(c); if (me.transformed) { cmp.setConfig(me.transformed); me.transformed = null; } }, init: Ext.emptyFn, privates: { transformInstanceConfig: function(config) { var transformed = this.callParent([ config ]); if (transformed.ptype) { transformed = Ext.apply({}, transformed); delete transformed.ptype; } this.transformed = transformed; var ret = Ext.apply({}, config); delete ret.ptype; delete ret.responsiveConfig; delete ret.responsiveFormulas; return ret; }, updateResponsiveState: function() { var config = this.getResponsiveState(); this.cmp.setConfig(config); } } }); Ext.define('Ext.plugin.Viewport', { extend: 'Ext.plugin.Responsive', alias: 'plugin.viewport', setCmp: function(cmp) { this.cmp = cmp; if (cmp && !cmp.isViewport) { this.decorate(cmp); if (cmp.renderConfigs) { cmp.flushRenderConfigs(); } cmp.setupViewport(); } }, statics: { decorate: function(target) { Ext.applyIf(target.prototype || target, { ariaRole: 'application', viewportCls: Ext.baseCSSPrefix + 'viewport' }); Ext.override(target, { isViewport: true, preserveElOnDestroy: true, initComponent: function() { this.callParent(); this.setupViewport(); }, getSizeModel: function() { var configured = Ext.layout.SizeModel.configured; return configured.pairsByHeightOrdinal[configured.ordinal]; }, handleViewportResize: function() { var me = this, Element = Ext.dom.Element, width = Element.getViewportWidth(), height = Element.getViewportHeight(); if (width !== me.width || height !== me.height) { me.setSize(width, height); } }, setupViewport: function() { var me = this, el = document.body; if (!el.id) { el.id = me.id; } el.setAttribute(Ext.Component.componentIdAttribute, me.id); el = me.el = Ext.getBody(); Ext.fly(document.documentElement).addCls(me.viewportCls); el.setHeight = el.setWidth = Ext.emptyFn; el.dom.scroll = 'no'; me.allowDomMove = false; me.renderTo = el; if (Ext.supports.Touch) { me.addMeta('apple-mobile-web-app-capable', 'yes'); } Ext.getScrollbarSize(); me.width = me.height = undefined; me.initialViewportHeight = Ext.Element.getViewportHeight(); me.initialViewportWidth = Ext.Element.getViewportWidth(); }, afterLayout: function(layout) { if (Ext.supports.Touch) { document.body.scrollTop = 0; } this.callParent([ layout ]); }, onRender: function() { var me = this; me.callParent(arguments); me.width = me.initialViewportWidth; me.height = me.initialViewportHeight; me.initialViewportWidth = me.initialViewportHeight = null; if (Ext.supports.TouchEvents) { me.mon(Ext.getDoc(), { touchmove: function(e) { e.preventDefault(); }, translate: false, delegated: false }); } }, initInheritedState: function(inheritedState, inheritedStateInner) { var me = this, root = Ext.rootInheritedState; if (inheritedState !== root) { me.initInheritedState(me.inheritedState = root, me.inheritedStateInner = Ext.Object.chain(root)); } else { me.callParent([ inheritedState, inheritedStateInner ]); } }, beforeDestroy: function() { var me = this, root = Ext.rootInheritedState, key; for (key in root) { if (key !== 'rtl') { delete root[key]; } } me.removeUIFromElement(); me.el.removeCls(me.baseCls); Ext.fly(document.body.parentNode).removeCls(me.viewportCls); me.callParent(); }, addMeta: function(name, content) { var meta = document.createElement('meta'); meta.setAttribute('name', name); meta.setAttribute('content', content); Ext.getHead().appendChild(meta); }, privates: { applyTargetCls: function(targetCls) { this.el.addCls(targetCls); }, disableTabbing: function() { var el = this.el; if (el) { el.saveChildrenTabbableState(); } }, enableTabbing: function() { var el = this.el; if (el) { el.restoreChildrenTabbableState(); } }, getOverflowEl: function() { return Ext.get(document.documentElement); } } }); } }, privates: { updateResponsiveState: function() { this.cmp.handleViewportResize(); this.callParent(); } } }, function(Viewport) { Viewport.prototype.decorate = Viewport.decorate; }); Ext.define('Ext.container.Viewport', { extend: 'Ext.container.Container', requires: [ 'Ext.plugin.Viewport' ], mixins: [ 'Ext.mixin.Responsive' ], alias: 'widget.viewport', alternateClassName: 'Ext.Viewport', privates: { updateResponsiveState: function() { this.handleViewportResize(); this.mixins.responsive.updateResponsiveState.call(this); } } }, function() { Ext.plugin.Viewport.decorate(this); }); Ext.define('Ext.layout.container.Anchor', { alias: 'layout.anchor', extend: 'Ext.layout.container.Auto', alternateClassName: 'Ext.layout.AnchorLayout', type: 'anchor', defaultAnchor: '100%', parseAnchorRE: /^(r|right|b|bottom)$/i, manageOverflow: true, setsItemSize: true, beginLayoutCycle: function(ownerContext) { var me = this, dimensions = 0, anchorSpec, childContext, childItems, i, length; me.callParent(arguments); childItems = ownerContext.childItems; length = childItems.length; for (i = 0; i < length; ++i) { childContext = childItems[i]; anchorSpec = childContext.target.anchorSpec; if (anchorSpec) { if (childContext.widthModel.calculated && anchorSpec.right) { dimensions |= 1; } if (childContext.heightModel.calculated && anchorSpec.bottom) { dimensions |= 2; } if (dimensions === 3) { break; } } } ownerContext.anchorDimensions = dimensions; me.sanityCheck(ownerContext); }, calculateItems: function(ownerContext, containerSize) { var me = this, childItems = ownerContext.childItems, length = childItems.length, gotHeight = containerSize.gotHeight, gotWidth = containerSize.gotWidth, ownerHeight = containerSize.height, ownerWidth = containerSize.width, knownDimensions = (gotWidth ? 1 : 0) | (gotHeight ? 2 : 0), anchorDimensions = ownerContext.anchorDimensions, anchorSpec, childContext, childMargins, height, i, width; if (!anchorDimensions) { return true; } for (i = 0; i < length; i++) { childContext = childItems[i]; childMargins = childContext.getMarginInfo(); anchorSpec = childContext.target.anchorSpec; if (gotWidth && childContext.widthModel.calculated) { width = anchorSpec.right(ownerWidth) - childMargins.width; width = me.adjustWidthAnchor(width, childContext); childContext.setWidth(width); } if (gotHeight && childContext.heightModel.calculated) { height = anchorSpec.bottom(ownerHeight) - childMargins.height; height = me.adjustHeightAnchor(height, childContext); childContext.setHeight(height); } } return (knownDimensions & anchorDimensions) === anchorDimensions; }, sanityCheck: function(ownerContext) { var shrinkWrapWidth = ownerContext.widthModel.shrinkWrap, shrinkWrapHeight = ownerContext.heightModel.shrinkWrap, children = ownerContext.childItems, anchorSpec, comp, childContext, i, length; for (i = 0 , length = children.length; i < length; ++i) { childContext = children[i]; comp = childContext.target; anchorSpec = comp.anchorSpec; if (anchorSpec) { if (childContext.widthModel.calculated && anchorSpec.right) { if (shrinkWrapWidth) { Ext.log({ level: 'warn', msg: 'Right anchor on ' + comp.id + ' in shrinkWrap width container' }); } } if (childContext.heightModel.calculated && anchorSpec.bottom) { if (shrinkWrapHeight) { Ext.log({ level: 'warn', msg: 'Bottom anchor on ' + comp.id + ' in shrinkWrap height container' }); } } } } }, anchorFactory: { offset: function(delta) { return function(v) { return v + delta; }; }, ratio: function(ratio) { return function(v) { return Math.floor(v * ratio); }; }, standard: function(diff) { return function(v) { return v - diff; }; } }, parseAnchor: function(a, start, cstart) { if (a && a !== 'none') { var factory = this.anchorFactory, delta; if (this.parseAnchorRE.test(a)) { return factory.standard(cstart - start); } if (a.indexOf('%') !== -1) { return factory.ratio(parseFloat(a.replace('%', '')) * 0.01); } delta = parseInt(a, 10); if (!isNaN(delta)) { return factory.offset(delta); } } return null; }, adjustWidthAnchor: function(value, childContext) { return value; }, adjustHeightAnchor: function(value, childContext) { return value; }, configureItem: function(item) { var me = this, owner = me.owner, anchor = item.anchor, anchorsArray, anchorWidth, anchorHeight; me.callParent(arguments); if (!item.anchor && item.items && !Ext.isNumber(item.width)) { item.anchor = anchor = me.defaultAnchor; } if (owner.anchorSize) { if (typeof owner.anchorSize === 'number') { anchorWidth = owner.anchorSize; } else { anchorWidth = owner.anchorSize.width; anchorHeight = owner.anchorSize.height; } } else { anchorWidth = owner.initialConfig.width; anchorHeight = owner.initialConfig.height; } if (anchor) { anchorsArray = anchor.split(' '); item.anchorSpec = { right: me.parseAnchor(anchorsArray[0], item.initialConfig.width, anchorWidth), bottom: me.parseAnchor(anchorsArray[1], item.initialConfig.height, anchorHeight) }; } }, sizePolicy: { $: { readsWidth: 1, readsHeight: 1, setsWidth: 0, setsHeight: 0 }, b: { readsWidth: 1, readsHeight: 0, setsWidth: 0, setsHeight: 1 }, r: { $: { readsWidth: 0, readsHeight: 1, setsWidth: 1, setsHeight: 0 }, b: { readsWidth: 0, readsHeight: 0, setsWidth: 1, setsHeight: 1 } } }, getItemSizePolicy: function(item) { var anchorSpec = item.anchorSpec, key = '$', policy = this.sizePolicy, sizeModel; if (anchorSpec) { sizeModel = this.owner.getSizeModel(); if (anchorSpec.right && !sizeModel.width.shrinkWrap) { policy = policy.r; } if (anchorSpec.bottom && !sizeModel.height.shrinkWrap) { key = 'b'; } } return policy[key]; } }); Ext.define('Ext.dashboard.Panel', { extend: 'Ext.panel.Panel', xtype: 'dashboard-panel', cls: Ext.baseCSSPrefix + 'dashboard-panel', anchor: '100%', layout: 'fit', frame: true, closable: true, collapsible: true, animCollapse: true, titleCollapse: true, stateful: true, draggable: { moveOnDrag: false }, animateClose: true, loadMask: true, loadMessage: 'Loading...', minHeight: 90, resizable: true, resizeHandles: 's', doClose: function() { var me = this; if (me.animateClose) { if (!me.closing) { me.closing = true; me.el.animate({ opacity: 0, callback: me.finishClose, scope: me }); } } else { me.finishClose(); } }, finishClose: function() { var me = this, closeAction = me.closeAction; me.closing = false; me.fireEvent('close', me); Ext.suspendLayouts(); me[closeAction](); Ext.resumeLayouts(true); if (closeAction === 'hide') { me.el.setOpacity(1); } }, afterRender: function() { this.callParent(); if (this.loading) { this.onViewBeforeLoad(); } }, getLoadMask: function() { var me = this, loadMask = me.rendered && me.loadMask, config; if (loadMask && !loadMask.isComponent) { config = { target: me }; if (loadMask === true) { loadMask = config; } else { Ext.apply(config, loadMask); } me.loadMask = loadMask = Ext.ComponentManager.create(config, 'loadmask'); } return loadMask || null; }, onAdd: function(view) { this.callParent(arguments); view.on({ beforeload: 'onViewBeforeLoad', load: 'onViewLoaded', scope: this }); }, onViewBeforeLoad: function() { this.loading = true; var loadMask = this.getLoadMask(); if (loadMask) { loadMask.show(); } }, onViewLoaded: function() { this.loading = false; var loadMask = this.getLoadMask(); if (loadMask) { loadMask.hide(); } var view = this.items.getAt(0); if (view.getTitle) { var title = view.getTitle(); if (title) { this.setTitle(title); } } }, setBox: function(box) { this.setSize(box.width, box.height); }, getState: function() { var me = this, state = me.callParent() || {}; if (!state.collapsed) { me.addPropertyToState(state, 'height', me.rendered ? me.getHeight() : me.height || me.minHeight || 100); } return state; } }); Ext.define('Ext.dashboard.Column', { extend: 'Ext.container.Container', xtype: 'dashboard-column', requires: [ 'Ext.layout.container.Anchor', 'Ext.dashboard.Panel' ], layout: 'anchor', isDashboardColumn: true, defaultType: 'dashboard-panel', cls: Ext.baseCSSPrefix + 'dashboard-column', synthetic: true, onRemove: function(dashPanel, isDestroying) { var me = this, ownerCt = me.ownerCt, remainingSiblings, numRemaining, totalColumnWidth = 0, i; if (ownerCt && me.items.getCount() === 0) { remainingSiblings = Ext.Array.filter(ownerCt.query('>' + me.xtype + '[rowIndex=' + me.rowIndex + ']'), function(c) { return c !== me; }); numRemaining = remainingSiblings.length; if (!me.destroying && !me.isDestroyed) { ownerCt.remove(me); if (numRemaining === 1) { remainingSiblings[0].columnWidth = 1; } else { for (i = 0; i < numRemaining; i++) { totalColumnWidth += remainingSiblings[i].columnWidth || 0; } for (i = 0; i < numRemaining; i++) { remainingSiblings[i].columnWidth = remainingSiblings[i].columnWidth / totalColumnWidth; } } if (isDestroying) { ownerCt.updateLayout(); } } } } }); Ext.define('Ext.layout.container.Column', { extend: 'Ext.layout.container.Auto', alias: [ 'layout.column' ], alternateClassName: 'Ext.layout.ColumnLayout', type: 'column', itemCls: Ext.baseCSSPrefix + 'column', targetCls: Ext.baseCSSPrefix + 'column-layout-ct', clearSide: 'left', columnWidthSizePolicy: { readsWidth: 0, readsHeight: 1, setsWidth: 1, setsHeight: 0 }, createsInnerCt: true, manageOverflow: true, setsItemSize: true, needsItemSize: true, isItemShrinkWrap: function(item) { return true; }, getItemSizePolicy: function(item, ownerSizeModel) { if (item.columnWidth) { if (!ownerSizeModel) { ownerSizeModel = this.owner.getSizeModel(); } if (!ownerSizeModel.width.shrinkWrap) { return this.columnWidthSizePolicy; } } return this.autoSizePolicy; }, calculateItems: function(ownerContext, containerSize) { var me = this, columnCount = me.columnCount, targetContext = ownerContext.targetContext, items = ownerContext.childItems, len = items.length, contentWidth = 0, gotWidth = containerSize.gotWidth, blocked, availableWidth, i, itemContext, itemMarginWidth, itemWidth; if (gotWidth === false) { targetContext.domBlock(me, 'width'); blocked = true; } else if (gotWidth) { availableWidth = containerSize.width; } else { return true; } for (i = 0; i < len; ++i) { itemContext = items[i]; if (columnCount) { if (i % columnCount) { itemContext.setProp('clear', null); } else { itemContext.setProp('clear', me.clearSide); } } itemMarginWidth = itemContext.getMarginInfo().width; if (!itemContext.widthModel.calculated) { itemWidth = itemContext.getProp('width'); if (typeof itemWidth !== 'number') { itemContext.block(me, 'width'); blocked = true; } contentWidth += itemWidth + itemMarginWidth; } } if (!blocked) { availableWidth = (availableWidth < contentWidth) ? 0 : availableWidth - contentWidth; for (i = 0; i < len; ++i) { itemContext = items[i]; if (itemContext.widthModel.calculated) { itemMarginWidth = itemContext.marginInfo.width; itemWidth = itemContext.target.columnWidth; itemWidth = Math.floor(itemWidth * availableWidth) - itemMarginWidth; itemWidth = itemContext.setWidth(itemWidth); contentWidth += itemWidth + itemMarginWidth; } } ownerContext.setContentWidth(contentWidth + ownerContext.paddingContext.getPaddingInfo().width); } return !blocked; } }); Ext.define('Ext.resizer.SplitterTracker', { extend: 'Ext.dd.DragTracker', requires: [ 'Ext.util.Region' ], enabled: true, overlayCls: Ext.baseCSSPrefix + 'resizable-overlay', createDragOverlay: function() { var overlay, El = Ext.dom.Element; overlay = this.overlay = Ext.getBody().createChild({ role: 'presentation', cls: this.overlayCls, html: ' ' }); overlay.unselectable(); overlay.setSize(El.getDocumentWidth(), El.getDocumentHeight()); overlay.show(); }, getPrevCmp: function() { var splitter = this.getSplitter(); return splitter.previousSibling(':not([hidden])'); }, getNextCmp: function() { var splitter = this.getSplitter(); return splitter.nextSibling(':not([hidden])'); }, onBeforeStart: function(e) { var me = this, prevCmp = me.getPrevCmp(), nextCmp = me.getNextCmp(), collapseEl = me.getSplitter().collapseEl, target = e.getTarget(), box; if (!prevCmp || !nextCmp) { return false; } if (collapseEl && target === collapseEl.dom) { return false; } if (nextCmp.collapsed || prevCmp.collapsed) { return false; } me.prevBox = prevCmp.getEl().getBox(); me.nextBox = nextCmp.getEl().getBox(); me.constrainTo = box = me.calculateConstrainRegion(); if (!box) { return false; } return box; }, onStart: function(e) { var splitter = this.getSplitter(); this.createDragOverlay(); splitter.addCls(splitter.baseCls + '-active'); }, onResizeKeyDown: function(e) { var me = this, splitter = me.getSplitter(), key = e.getKey(), incrIdx = splitter.orientation === 'vertical' ? 0 : 1, incr = key === e.UP || key === e.LEFT ? -1 : 1, easing; if (!me.active && me.onBeforeStart(e)) { Ext.fly(e.target).on('keyup', me.onResizeKeyUp, me); me.triggerStart(e); me.onMouseDown(e); me.startXY = splitter.getXY(); me.lastKeyDownXY = Ext.Array.slice(me.startXY); easing = me.easing = new Ext.fx.easing.Linear(); easing.setStartTime(Ext.Date.now()); easing.setStartValue(1); easing.setEndValue(4); easing.setDuration(2000); } if (me.active) { me.lastKeyDownXY[incrIdx] = Math.round(me.lastKeyDownXY[incrIdx] + (incr * me.easing.getValue())); me.lastXY = me.lastKeyDownXY; splitter.setXY(me.getXY('dragTarget')); } }, onResizeKeyUp: function(e) { this.onMouseUp(e); }, calculateConstrainRegion: function() { var me = this, splitter = me.getSplitter(), splitWidth = splitter.getWidth(), defaultMin = splitter.defaultSplitMin, orient = splitter.orientation, prevBox = me.prevBox, prevCmp = me.getPrevCmp(), nextBox = me.nextBox, nextCmp = me.getNextCmp(), prevConstrainRegion, nextConstrainRegion, constrainOptions; if (orient === 'vertical') { constrainOptions = { prevCmp: prevCmp, nextCmp: nextCmp, prevBox: prevBox, nextBox: nextBox, defaultMin: defaultMin, splitWidth: splitWidth }; prevConstrainRegion = new Ext.util.Region(prevBox.y, me.getVertPrevConstrainRight(constrainOptions), prevBox.bottom, me.getVertPrevConstrainLeft(constrainOptions)); nextConstrainRegion = new Ext.util.Region(nextBox.y, me.getVertNextConstrainRight(constrainOptions), nextBox.bottom, me.getVertNextConstrainLeft(constrainOptions)); } else { prevConstrainRegion = new 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 = new 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 prevConstrainRegion.intersect(nextConstrainRegion); }, performResize: function(e, offset) { var me = this, splitter = me.getSplitter(), orient = splitter.orientation, prevCmp = me.getPrevCmp(), nextCmp = me.getNextCmp(), owner = splitter.ownerCt, flexedSiblings = owner.query('>[flex]'), len = flexedSiblings.length, vertical = orient === 'vertical', i = 0, dimension = vertical ? 'width' : 'height', totalFlex = 0, item, size; for (; i < len; i++) { item = flexedSiblings[i]; size = vertical ? item.getWidth() : item.getHeight(); totalFlex += size; item.flex = size; } offset = vertical ? offset[0] : offset[1]; if (prevCmp) { size = me.prevBox[dimension] + offset; if (prevCmp.flex) { prevCmp.flex = size; } else { prevCmp[dimension] = size; } } if (nextCmp) { size = me.nextBox[dimension] - offset; if (nextCmp.flex) { nextCmp.flex = size; } else { nextCmp[dimension] = size; } } owner.updateLayout(); }, endDrag: function() { var me = this; if (me.overlay) { me.overlay.destroy(); delete me.overlay; } me.callParent(arguments); }, onEnd: function(e) { var me = this, splitter = me.getSplitter(); splitter.removeCls(splitter.baseCls + '-active'); me.performResize(e, me.getResizeOffset()); }, onDrag: function(e) { var me = this, offset = me.getOffset('dragTarget'), splitter = me.getSplitter(), splitEl = splitter.getEl(), orient = splitter.orientation; if (orient === "vertical") { splitEl.setX(me.startRegion.left + offset[0]); } else { splitEl.setY(me.startRegion.top + offset[1]); } }, getSplitter: function() { return this.splitter; }, getVertPrevConstrainRight: function(o) { return (o.prevCmp.maxWidth ? o.prevBox.x + o.prevCmp.maxWidth : o.nextBox.right - (o.nextCmp.minWidth || o.defaultMin)) + o.splitWidth; }, getVertPrevConstrainLeft: function(o) { return o.prevBox.x + (o.prevCmp.minWidth || o.defaultMin); }, getVertNextConstrainRight: function(o) { return o.nextBox.right - (o.nextCmp.minWidth || o.defaultMin); }, getVertNextConstrainLeft: function(o) { return (o.nextCmp.maxWidth ? o.nextBox.right - o.nextCmp.maxWidth : o.prevBox.x + (o.prevBox.minWidth || o.defaultMin)) - o.splitWidth; }, getResizeOffset: function() { return this.getOffset('dragTarget'); } }); Ext.define('Ext.layout.container.ColumnSplitterTracker', { extend: 'Ext.resizer.SplitterTracker', onStart: function(e) { Ext.apply(this.getSplitter().el.dom.style, { top: 0, left: 0 }); this.callParent(arguments); }, endDrag: function() { var me = this; me.callParent(arguments); me.getSplitter().el.dom.style.left = 0; }, performResize: function(e, offset) { var me = this, prevCmp = me.getPrevCmp(), nextCmp = me.getNextCmp(), splitter = me.getSplitter(), owner = splitter.ownerCt, delta = offset[0], prevWidth, nextWidth, ratio; if (prevCmp && nextCmp) { prevCmp.width = prevWidth = me.prevBox.width + delta; nextCmp.width = nextWidth = me.nextBox.width - delta; ratio = (prevCmp.columnWidth + nextCmp.columnWidth) / (prevWidth + nextWidth); prevCmp.columnWidth = prevWidth * ratio; nextCmp.columnWidth = nextWidth * ratio; } owner.updateLayout(); } }); Ext.define('Ext.layout.container.ColumnSplitter', { extend: 'Ext.resizer.Splitter', xtype: 'columnsplitter', requires: [ 'Ext.layout.container.ColumnSplitterTracker' ], isSplitter: true, synthetic: true, cls: Ext.baseCSSPrefix + 'splitter-vertical', orientation: 'vertical', collapseDirection: 'left', trackerClass: 'Ext.layout.container.ColumnSplitterTracker', width: 7, height: 1, getTrackerConfig: function() { var tracker = this.callParent(); tracker.xclass = this.trackerClass; return tracker; } }); Ext.define('Ext.layout.container.Dashboard', { extend: 'Ext.layout.container.Column', alias: 'layout.dashboard', requires: [ 'Ext.layout.container.ColumnSplitter' ], type: 'dashboard', firstColumnCls: Ext.baseCSSPrefix + 'dashboard-column-first', lastColumnCls: Ext.baseCSSPrefix + 'dashboard-column-last', getSplitterConfig: function() { return { xtype: 'columnsplitter' }; }, getColumns: function(items) { var array = Ext.Array; return array.filter(array.from(items), function(item) { return item.target && item.target.isSplitter !== true; }); }, beginLayout: function(ownerContext) { var me = this; me.callParent([ ownerContext ]); var childItems = ownerContext.childItems, rows = (ownerContext.rows = []), length = childItems.length, totalWidth = 2, columnTargets = 0, lastRow = 0, maxColumns = me.owner.getMaxColumns(), child, i, prev, row, splitter, target, width; for (i = 0; i < length; ++i) { target = (child = childItems[i]).target; splitter = target && target.isSplitter; columnTargets += (splitter ? 0 : 1); width = splitter ? 0 : target.columnWidth || 1; if (totalWidth + width > 1 || (maxColumns && (columnTargets > maxColumns))) { if (prev) { prev.orphan = 1; prev.el.setHeight(0); } totalWidth = 0; columnTargets = 1; if (rows.length) { lastRow = rows.length - 1; me.syncFirstLast(me.getColumns(rows[lastRow].items)); } rows.push(row = { index: rows.length, items: [], maxHeight: 0 }); } totalWidth += width; row.items.push(child); child.row = row; target.rowIndex = row.index; if (splitter) { child.el.setHeight(1); } prev = child; } if (rows.length) { me.syncFirstLast(me.getColumns(rows[rows.length - 1].items)); } }, beforeLayoutCycle: function(ownerContext) { var me = this, items = me.owner.items; if (me.splitterGen !== items.generation) { me.syncSplitters(); me.splitterGen = items.generation; } me.callParent(arguments); }, finishedLayout: function(ownerContext) { var items = ownerContext.childItems, len = items.length, box, child, i, target, row; this.callParent([ ownerContext ]); for (i = 0; i < len; i += 2) { target = (child = items[i]).target; box = target.lastBox; row = child.row; row.maxHeight = Math.max(row.maxHeight, box.height); target.width = box.width; } for (i = 1; i < len; i += 2) { target = (child = items[i]).target; if (!child.orphan) { target.el.setHeight(child.row.maxHeight); } } }, syncSplitters: function() { var me = this, owner = me.owner, items = owner.items.items, index = items.length, ok = true, shouldBeSplitter = false, item, splitter; while (index-- > 0) { item = items[index]; if (shouldBeSplitter) { if (item.isSplitter) { shouldBeSplitter = false; } else { if (ok) { ok = false; owner.suspendLayouts(); } splitter = owner.add(index + 1, me.getSplitterConfig()); } } else { if (item.isSplitter) { if (ok) { ok = false; owner.suspendLayouts(); } owner.remove(item); } else { shouldBeSplitter = true; } } } while (items.length && (item = items[0]).isSplitter) { if (ok) { ok = false; owner.suspendLayouts(); } owner.remove(item); } if (!ok) { owner.resumeLayouts(); } }, syncFirstLast: function(items) { var me = this, firstCls = me.firstColumnCls, lastCls = me.lastColumnCls, len, firstAndLast = [ firstCls, lastCls ], i, item, last; items = Ext.Array.from(items); len = items.length; for (i = 0; i < len; ++i) { item = items[i].target; last = (i === len - 1); if (!i) { if (last) { item.addCls(firstAndLast); } else { item.addCls(firstCls); item.removeCls(lastCls); } } else if (last) { item.addCls(lastCls); item.removeCls(firstCls); } else { item.removeCls(firstAndLast); } } } }); Ext.define('Ext.dashboard.DropZone', { extend: 'Ext.dd.DropTarget', ddScrollConfig: { vthresh: 75, hthresh: -1, animate: true, increment: 200 }, containerScroll: true, overClass: Ext.baseCSSPrefix + 'dashboard-dd-over', constructor: function(dashboard, cfg) { this.dashboard = dashboard; dashboard.body.ddScrollConfig = this.ddScrollConfig; this.callParent([ dashboard.body, cfg ]); }, getOverEvent: function(dd, e, data) { var dashboard = this.dashboard, dbody = dashboard.body, items = dashboard.items.items, bodyBox = dbody.getBox(), count = items.length, xy = e.getXY(), x = xy[0] - bodyBox.x + dbody.getScrollLeft(), y = xy[1] - bodyBox.y + dbody.getScrollTop(), over = { columnIndex: 0, column: null, dashboard: dashboard, above: null, extensible: false, beforeAfter: 0, data: data, panel: data.panel, rawEvent: e, source: dd, status: this.dropAllowed }, t, ht, i, k, item, w, childCount, childItems, childItem; for (i = 0; i < count; i += 2) { item = items[i]; w = item.lastBox.width; if (items[i + 1]) { w += items[i + 1].lastBox.width; } if (e.within(item.el)) { over.columnIndex = i; over.column = item; over.extensible = this.isRowExtensible(item.rowIndex); t = Math.min(80, w * 0.2); over.beforeAfter = t = (over.extensible && ((x < t) ? -1 : ((x > w - t) ? 1 : 0))); if (!t || !over.extensible) { childItems = item.items.items; for (k = 0 , childCount = childItems.length; k < childCount; ++k) { childItem = childItems[k]; ht = childItem.el.getHeight(); if (y < ht / 2) { over.above = childItem; break; } y -= ht; } } break; } x -= w; } return over; }, notifyOver: function(dd, e, data) { var me = this, dashboard = me.dashboard, over = me.getOverEvent(dd, e, data), colEl = over.column && over.column.el, proxy = dd.proxy, proxyProxy, aboveItem = over.above, colWidth, width = 0, padding, hasListeners = dashboard.hasListeners; data.lastOver = over; if ((!hasListeners.validatedrop || dashboard.fireEvent('validatedrop', over) !== false) && (!hasListeners.beforedragover || dashboard.fireEvent('beforedragover', over) !== false)) { proxyProxy = dd.panelProxy.getProxy(); proxy.getProxy().setWidth('auto'); if (colEl) { width = colWidth = colEl.getWidth(); if (over.beforeAfter) { dd.panelProxy.moveProxy(colEl.dom, colEl.dom.firstChild); width = colWidth / 2; proxyProxy.setWidth(width); } else { if (aboveItem) { dd.panelProxy.moveProxy(aboveItem.el.dom.parentNode, aboveItem.el.dom); } else { dd.panelProxy.moveProxy(colEl.dom, null); } proxyProxy.setWidth('auto'); } if (width) {} proxyProxy.setStyle({ 'float': 'none', 'clear': 'none', 'margin-left': (over.beforeAfter > 0) ? (colWidth - width - colEl.getPadding('lr')) + 'px' : '', 'margin-top': '7px' }); } else { padding = dashboard.body.getPadding('lr'); proxyProxy.setStyle({ 'float': 'left', 'clear': 'left', 'margin': '0 7px 0 7px' }); proxyProxy.setWidth(dashboard.body.getWidth() - padding); dd.panelProxy.moveProxy(dashboard.body.dom.firstChild.firstChild, null); } this.scrollPos = dashboard.body.getScroll(); if (hasListeners.dragover) { dashboard.fireEvent('dragover', over); } } return over.status; }, isRowExtensible: function(rowIndex) { var me = this, dashboard = me.dashboard, maxColumns = dashboard.getMaxColumns() || 1; return Ext.Array.from(dashboard.query('>dashboard-column[rowIndex=' + rowIndex + ']')).length < maxColumns; }, notifyDrop: function(dd, e, data) { this.callParent(arguments); var dashboard = this.dashboard, over = data.lastOver, panel = over.panel, fromCt = panel.ownerCt, toCt = over.column, side = toCt ? over.beforeAfter : 1, currentIndex = fromCt.items.indexOf(panel), newIndex = toCt ? (over.above ? toCt.items.indexOf(over.above) : toCt.items.getCount()) : 0, colIndex, newCol, hasListeners = dashboard.hasListeners; if (fromCt === toCt) { if (fromCt.items.getCount() === 1) { return; } if (!side) { if (currentIndex < newIndex) { --newIndex; } if (currentIndex === newIndex) { return; } } } if ((hasListeners.validatedrop && dashboard.fireEvent('validatedrop', over) === false) || (hasListeners.beforedrop && dashboard.fireEvent('beforedrop', over) === false)) { return; } Ext.suspendLayouts(); panel.isMoving = true; if (side) { colIndex = dashboard.items.indexOf(toCt); if (colIndex < 0) { colIndex = dashboard.items.getCount(); } else if (side > 0) { ++colIndex; } newCol = dashboard.createColumn(); if (toCt) { newCol.columnWidth = toCt.columnWidth = toCt.columnWidth / 2; delete toCt.width; } else { newCol.columnWidth = 1; } toCt = dashboard.insert(colIndex, newCol); newIndex = 0; } panel.el.dom.style.display = ''; toCt.insert(newIndex, panel); panel.isMoving = false; toCt.updateLayout(); Ext.resumeLayouts(true); if (hasListeners.drop) { dashboard.fireEvent('drop', over); } } }); Ext.define('Ext.dashboard.Part', { mixins: [ 'Ext.mixin.Factoryable', 'Ext.mixin.Identifiable' ], requires: [ 'Ext.util.ObjectTemplate' ], alias: 'part.part', factoryConfig: { type: 'part' }, isPart: true, _lastId: 0, config: { id: null, dashboard: null, viewTemplate: { collapsed: '{collapsed}', columnIndex: '{columnIndex}', id: '{id}', title: '{title}', height: '{height}' } }, viewTemplateOptions: { excludeProperties: { bind: 1 } }, valueRe: /^[{][a-z]*[}]$/i, constructor: function(config) { this.initConfig(config); }, applyViewTemplate: function(template) { if (!Ext.isObject(template)) { Ext.Error.raise('The viewTemplate for ' + this.$className + ' is not an Object'); } return Ext.util.ObjectTemplate.create(template, this.viewTemplateOptions); }, displayForm: function(instance, currentConfig, callback, scope) { callback.call(scope || this, {}); }, createView: function(config) { var me = this, template = me.getViewTemplate(), ret = template.apply(config); ret.dashboard = me.getDashboard(); ret.part = me; ret._partConfig = config; return ret; } }); Ext.define('Ext.dashboard.Dashboard', { extend: 'Ext.panel.Panel', xtype: 'dashboard', requires: [ 'Ext.layout.container.Dashboard', 'Ext.dashboard.DropZone', 'Ext.dashboard.Column', 'Ext.dashboard.Part' ], isDashboard: true, cls: Ext.baseCSSPrefix + 'dashboard', bodyCls: Ext.baseCSSPrefix + 'dashboard-body', defaultType: 'dashboard-column', scrollable: true, layout: null, stateful: false, idSeed: 1, config: { parts: null }, renderConfig: { maxColumns: 4 }, initComponent: function() { var me = this; if (!me.layout) { me.layout = { type: 'dashboard' }; } me.callParent(); }, applyParts: function(parts, collection) { if (!collection) { collection = new Ext.util.Collection({ decoder: Ext.Factory.part }); } var id, part; for (id in parts) { part = parts[id]; if (Ext.isString(part)) { part = { type: part }; } part.id = id; part.dashboard = this; collection.add(part); } return collection; }, getPart: function(type) { var parts = this.getParts(); return parts.getByKey(type); }, addNew: function(type, columnIndex, beforeAfter) { var me = this, part = me.getPart(type); part.displayForm(null, null, function(config) { config.type = type; me.addView(config, columnIndex, beforeAfter); }); }, addView: function(instance, columnIndex, beforeAfter) { var me = this, items = me.query('dashboard-column'), count = items.length, index = columnIndex || 0, view = instance.id ? instance : me.createView(instance), columnWidths = me.columnWidths, column; if (!count) { column = me.add(0, me.createColumn({ columnWidth: (Ext.isArray(columnWidths) ? columnWidths[0] : 1) })); items = [ column ]; count = 1; } if (index >= count) { index = count - 1; beforeAfter = 1; } if (!beforeAfter) { column = items[index]; if (column) { return column.add(view); } } if (beforeAfter > 0) { ++index; } column = me.createColumn(); if (columnWidths) { column.columnWidth = columnWidths[index] || (columnWidths[index] = 1); } if (!column.items) { column.items = []; } column.items.push(view); column = me.add(column); return column.items.first(); }, createColumn: function(config) { var cycle = this.cycleLayout; return Ext.apply({ items: [], bubbleEvents: [ 'add', 'remove', 'childmove', 'resize' ], listeners: { remove: this.onRemoveItem, expand: cycle, collapse: cycle, scope: this } }, config); }, createView: function(config) { var me = this, type = config.type, part = me.getPart(type), view = part.createView(config); if (!view.id) { view.id = me.id + '_' + type + (me.idSeed++); } view.bubbleEvents = Ext.Array.from(view.bubbleEvents).concat([ 'expand', 'collapse' ]); view.stateful = me.stateful; return view; }, initEvents: function() { this.callParent(); this.dd = new Ext.dashboard.DropZone(this, this.dropConfig); }, cycleLayout: function() { this.updateLayout(); }, beforeDestroy: function() { if (this.dd) { Ext.destroy(this.dd); } this.callParent(); }, applyState: function(state) { delete state.items; var me = this; me.callParent([ state ]); var columnWidths = state.columnWidths, items = me.items.items, length = items.length, i, n; if (columnWidths) { n = columnWidths.length; me.columnWidths = []; for (i = 0; i < length; ++i) { me.columnWidths.push(items[i].columnWidth = (i < n) ? columnWidths[i] : (1 / length)); } } }, getState: function() { var me = this, columnWidths = [], items = me.items.items, state = me.callParent() || {}, length = items.length, i, item; for (i = 0; i < length; ++i) { if (!(item = items[i]).isSplitter) { columnWidths.push(item.columnWidth); } } state.columnWidths = columnWidths; state.idSeed = me.idSeed; state.items = me.serializeItems(); me.columnWidths = columnWidths; return state; }, initItems: function() { var me = this, defaultContent = me.defaultContent, state; if (me.stateful) { state = Ext.state.Manager.get(me.getStateId()); defaultContent = (state && state.items) || defaultContent; } if (!me.items && defaultContent) { me.items = me.deserializeItems(defaultContent); } me.callParent(); }, deserializeItems: function(serialized) { var me = this, length = serialized.length, columns = [], columnWidths = me.columnWidths, maxColumns = me.getMaxColumns(), column, columnIndex, columnWidth, i, item, partConfig; for (i = 0; i < length; ++i) { partConfig = serialized[i]; columnIndex = Math.min(partConfig.columnIndex || 0, maxColumns - 1); delete partConfig.columnIndex; if (!(column = columns[columnIndex])) { columns[columnIndex] = column = me.createColumn(); columnWidth = columnWidths && columnWidths[columnIndex]; if (columnWidth) { column.columnWidth = columnWidth; } } item = me.createView(partConfig); column.items.push(item); } for (i = 0 , length = columns.length; i < length; ++i) { column = columns[i]; if (!column.columnWidth) { column.columnWidth = 1 / length; } } return columns; }, serializeItem: function(item) { return Ext.apply({ type: item.part.id, id: item.id, columnIndex: item.columnIndex }, item._partConfig); }, serializeItems: function() { var me = this, items = me.items.items, length = items.length, ret = [], columnIndex = 0, child, childItems, i, item, j, k; for (i = 0; i < length; ++i) { item = items[i]; if (!item.isSplitter) { childItems = item.items.items; for (j = 0 , k = childItems.length; j < k; ++j) { child = childItems[j]; child.columnIndex = columnIndex; ret.push(me.serializeItem(child)); } ++columnIndex; } } return ret; }, onRemoveItem: function(column, item) { if (item.stateful && !item.isMoving) { Ext.state.Manager.clear(item.getStateId()); } } }); Ext.define('Ext.dom.Layer', { extend: 'Ext.Element', alternateClassName: 'Ext.Layer', isLayer: true, constructor: function(config, existingEl) { config = config || {}; var me = this, dh = Ext.DomHelper, cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body, hm = config.hideMode, cls = Ext.baseCSSPrefix + (config.fixed ? 'fixed-layer' : 'layer'), dom, id, element, shadowConfig; if (existingEl) { dom = Ext.getDom(existingEl); if (!dom.parentNode) { pel.appendChild(dom); } } if (!dom) { dom = dh.append(pel, config.dh || { tag: 'div', cls: cls }); } if (config.id) { dom.id = config.id; } id = dom.id; if (id) { element = Ext.cache[id]; if (element) { delete Ext.cache[id]; element.dom = null; } } this.callParent([ dom ]); if (existingEl) { me.addCls(cls); } if (config.preventSync) { me.preventSync = true; } if (config.cls) { me.addCls(config.cls); } me.constrain = config.constrain !== false; if (hm) { me.setVisibilityMode(Ext.Element[hm.toUpperCase()]); } else if (config.useDisplay) { me.setVisibilityMode(Ext.Element.DISPLAY); } else { me.setVisibilityMode(Ext.Element.VISIBILITY); } if (config.shadow) { me.shadowOffset = config.shadowOffset || 4; shadowConfig = { offset: me.shadowOffset, fixed: config.fixed }; if (config.shadow !== true) { shadowConfig.mode = config.shadow; } me.enableShadow(shadowConfig); } else { me.shadowOffset = 0; } if (config.shim) { me.enableShim({ fixed: config.fixed }); } if (config.hidden === true) { me.hide(); } else if (config.hidden === false) { me.show(); } } }); Ext.define('Ext.event.publisher.MouseEnterLeave', { extend: 'Ext.event.publisher.Dom', type: 'mouseEnterLeave' }, function(MouseEnterLeave) { var eventMap = { mouseover: 'mouseenter', mouseout: 'mouseleave' }; if (!Ext.supports.MouseEnterLeave) { MouseEnterLeave.override({ handledDomEvents: [ 'mouseover', 'mouseout' ], handledEvents: [ 'mouseenter', 'mouseleave' ], doDelegatedEvent: function(e) { var target, relatedTarget, id, el, type, event; e = this.callParent([ e ]); target = e.getTarget(); relatedTarget = e.getRelatedTarget(); if (relatedTarget && Ext.fly(target).contains(relatedTarget)) { return; } id = target.id; if (id) { el = Ext.cache[id]; if (el) { type = eventMap[e.type]; e = e.chain({ type: type }); if (el.hasListeners[type]) { event = el.events[type]; if (event) { event = event.directs; if (event) { e.setCurrentTarget(el.dom); event.fire(e, e.target); } } } } } } }); } MouseEnterLeave.instance = new MouseEnterLeave(); }); Ext.define('Ext.flash.Component', { extend: 'Ext.Component', alternateClassName: 'Ext.FlashComponent', alias: 'widget.flash', flashVersion: '9.0.115', backgroundColor: '#ffffff', wmode: 'opaque', swfWidth: '100%', swfHeight: '100%', expressInstall: false, renderTpl: [ '' ], initComponent: function() { if (!('swfobject' in window)) { Ext.Error.raise('The SWFObject library is not loaded. Ext.flash.Component requires SWFObject version 2.2 or later: http://code.google.com/p/swfobject/'); } if (!this.url) { Ext.Error.raise('The "url" config is required for Ext.flash.Component'); } this.callParent(); }, beforeRender: function() { this.callParent(); Ext.applyIf(this.renderData, { swfId: this.getSwfId() }); }, afterRender: function() { var me = this, flashParams = Ext.apply({}, me.flashParams), flashVars = Ext.apply({}, me.flashVars); me.callParent(); flashParams = Ext.apply({ allowScriptAccess: 'always', bgcolor: me.backgroundColor, wmode: me.wmode }, flashParams); flashVars = Ext.apply({ allowedDomain: document.location.hostname }, flashVars); new swfobject.embedSWF( me.url, me.getSwfId(), me.swfWidth, me.swfHeight, me.flashVersion, me.expressInstall ? me.statics.EXPRESS_INSTALL_URL : undefined, flashVars, flashParams, me.flashAttributes, me.swfCallback.bind(me)); }, 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); } }, getSwfId: function() { return this.swfId || (this.swfId = "extswf" + this.getAutoId()); }, onSuccess: function() { this.swf.setStyle('visibility', 'inherit'); }, 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(); }, statics: { EXPRESS_INSTALL_URL: 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf' } }); Ext.define('Ext.form.action.Action', { alternateClassName: 'Ext.form.Action', submitEmptyText: true, constructor: function(config) { if (config) { Ext.apply(this, config); } var params = config.params; if (Ext.isString(params)) { this.params = Ext.Object.fromQueryString(params); } }, run: Ext.emptyFn, onFailure: function(response) { var form = this.form, formActive = form && !form.destroying && !form.isDestroyed; this.response = response; this.failureType = Ext.form.action.Action.CONNECT_FAILURE; if (formActive) { form.afterAction(this, false); } }, processResponse: function(response) { this.response = response; if (!response.responseText && !response.responseXML) { return true; } return (this.result = this.handleResponse(response)); }, getUrl: function() { return this.url || this.form.url; }, getMethod: function() { return (this.method || this.form.method || 'POST').toUpperCase(); }, getParams: function() { return Ext.apply({}, this.params, this.form.baseParams); }, 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: { CLIENT_INVALID: 'client', SERVER_INVALID: 'server', CONNECT_FAILURE: 'connect', LOAD_FAILURE: 'load' } }); 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', run: function() { Ext.Ajax.request(Ext.apply(this.createCallback(), { method: this.getMethod(), url: this.getUrl(), headers: this.headers, params: this.getParams() })); }, onSuccess: function(response) { var result = this.processResponse(response), form = this.form, formActive = form && !form.destroying && !form.isDestroyed; if (result === true || !result.success || !result.data) { this.failureType = Ext.form.action.Action.LOAD_FAILURE; if (formActive) { form.afterAction(this, false); } return; } if (formActive) { 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.form.action.Submit', { extend: 'Ext.form.action.Action', alternateClassName: 'Ext.form.Action.Submit', alias: 'formaction.submit', type: 'submit', run: function() { var me = this, form = me.form; if (me.clientValidation === false || form.isValid()) { me.doSubmit(); } else { me.failureType = Ext.form.action.Action.CLIENT_INVALID; form.afterAction(me, false); } }, doSubmit: function() { var me = this, ajaxOptions = Ext.apply(me.createCallback(), { url: me.getUrl(), method: me.getMethod(), headers: me.headers }), form = me.form, jsonSubmit = me.jsonSubmit || form.jsonSubmit, paramsProp = jsonSubmit ? 'jsonData' : 'params', formInfo; if (form.hasUpload()) { formInfo = me.buildForm(); ajaxOptions.form = formInfo.formEl; ajaxOptions.isUpload = true; } else { ajaxOptions[paramsProp] = me.getParams(jsonSubmit); } Ext.Ajax.request(ajaxOptions); if (formInfo) { me.cleanup(formInfo); } }, cleanup: function(formInfo) { var formEl = formInfo.formEl, uploadEls = formInfo.uploadEls, uploadFields = formInfo.uploadFields, len = uploadFields.length, i, field; for (i = 0; i < len; ++i) { field = uploadFields[i]; if (!field.clearOnSubmit) { field.restoreInput(uploadEls[i]); } } if (formEl) { Ext.removeNode(formEl); } }, getParams: function(useModelValues) { var falseVal = false, configParams = this.callParent(), fieldParams = this.form.getValues(falseVal, falseVal, this.submitEmptyText !== falseVal, useModelValues, true); return Ext.apply({}, fieldParams, configParams); }, buildForm: function() { var me = this, fieldsSpec = [], formSpec, formEl, basicForm = me.form, params = me.getParams(), uploadFields = [], uploadEls = [], fields = basicForm.getFields().items, i, len = fields.length, field, key, value, v, vLen, el; for (i = 0; i < len; ++i) { field = fields[i]; if (field.isFileUpload()) { uploadFields.push(field); } } for (key in params) { if (params.hasOwnProperty(key)) { value = params[key]; if (Ext.isArray(value)) { vLen = value.length; for (v = 0; v < vLen; v++) { fieldsSpec.push(me.getFieldConfig(key, value[v])); } } else { fieldsSpec.push(me.getFieldConfig(key, value)); } } } formSpec = { tag: 'form', role: 'presentation', action: me.getUrl(), method: me.getMethod(), target: me.target ? (Ext.isString(me.target) ? me.target : Ext.fly(me.target).dom.name) : '_self', style: 'display:none', cn: fieldsSpec }; if (!formSpec.target) { Ext.Error.raise('Invalid form target.'); } if (uploadFields.length) { formSpec.encoding = formSpec.enctype = 'multipart/form-data'; } formEl = Ext.DomHelper.append(Ext.getBody(), formSpec); len = uploadFields.length; for (i = 0; i < len; ++i) { el = uploadFields[i].extractFileInput(); formEl.appendChild(el); uploadEls.push(el); } return { formEl: formEl, uploadFields: uploadFields, uploadEls: uploadEls }; }, getFieldConfig: function(name, value) { return { tag: 'input', type: 'hidden', name: name, value: Ext.String.htmlEncode(value) }; }, onSuccess: function(response) { var form = this.form, formActive = form && !form.destroying && !form.isDestroyed, success = true, result = this.processResponse(response); if (result !== true && !result.success) { if (result.errors && formActive) { form.markInvalid(result.errors); } this.failureType = Ext.form.action.Action.SERVER_INVALID; success = false; } if (formActive) { form.afterAction(this, success); } }, handleResponse: function(response) { var form = this.form, errorReader = form.errorReader, rs, errors, i, len, records, result; 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; } result = { success: rs.success, errors: errors }; } else { try { result = Ext.decode(response.responseText); } catch (e) { result = { success: false, errors: [] }; } } return result; } }); Ext.define('Ext.form.field.TextArea', { extend: 'Ext.form.field.Text', alias: [ 'widget.textareafield', 'widget.textarea' ], alternateClassName: 'Ext.form.TextArea', requires: [ 'Ext.XTemplate', 'Ext.util.DelayedTask' ], fieldSubTpl: [ '', { disableFormats: true } ], growMin: 60, growMax: 1000, growAppend: '\n-', enterIsSpecial: false, preventScrollbars: false, returnRe: /\r/g, inputCls: Ext.baseCSSPrefix + 'form-textarea', extraFieldBodyCls: Ext.baseCSSPrefix + 'form-textarea-body', constructor: function(config) { this.callParent([ config ]); if (this.cols) { Ext.log.warn('Ext.form.field.TextArea "cols" config was removed in Ext 5.0. Please specify a "width" or use a layout instead.'); } if (this.rows) { Ext.log.warn('Ext.form.field.TextArea "rows" config was removed in Ext 5.0. Please specify a "height" or use a layout instead.'); } }, getSubTplData: function(fieldData) { var me = this, fieldStyle = me.getFieldStyle(), ret = me.callParent(arguments); if (me.grow) { if (me.preventScrollbars) { ret.fieldStyle = (fieldStyle || '') + ';overflow:hidden;height:' + me.growMin + 'px'; } } return ret; }, afterRender: function() { var me = this; me.callParent(arguments); me.needsMaxCheck = me.enforceMaxLength && me.maxLength !== Number.MAX_VALUE && !Ext.supports.TextAreaMaxLength; if (me.needsMaxCheck) { me.inputEl.on('paste', me.onPaste, me); } }, transformRawValue: function(value) { return this.stripReturns(value); }, getValue: function() { return this.stripReturns(this.callParent()); }, valueToRaw: function(value) { value = this.stripReturns(value); return this.callParent([ value ]); }, stripReturns: function(value) { if (value && typeof value === 'string') { value = value.replace(this.returnRe, ''); } return value; }, onPaste: function() { var me = this; if (!me.pasteTask) { me.pasteTask = new Ext.util.DelayedTask(me.pasteCheck, me); } me.pasteTask.delay(1); }, pasteCheck: function() { var me = this, value = me.getValue(), max = me.maxLength; if (value.length > max) { value = value.substr(0, max); me.setValue(value); } }, fireKey: function(e) { var me = this, key = e.getKey(), value; if (e.isSpecialKey() && (me.enterIsSpecial || (key !== e.ENTER || e.hasModifier()))) { me.fireEvent('specialkey', me, e); } if (me.needsMaxCheck && key !== e.BACKSPACE && key !== e.DELETE && !e.isNavKeyPress() && !me.isCutCopyPasteSelectAll(e, key)) { value = me.getValue(); if (value.length >= me.maxLength) { e.stopEvent(); } } }, isCutCopyPasteSelectAll: function(e, key) { if (e.ctrlKey) { return key === e.A || key === e.C || key === e.V || key === e.X; } return false; }, autoSize: function() { var me = this, inputEl, height, curWidth, value; if (me.grow && me.rendered && me.getSizeModel().height.auto) { inputEl = me.inputEl; curWidth = inputEl.getWidth(true); value = Ext.util.Format.htmlEncode(inputEl.dom.value) || ' '; value += me.growAppend; value = value.replace(/\n/g, '
'); height = Ext.util.TextMetrics.measure(inputEl, value, curWidth).height + inputEl.getPadding('tb') + me.inputWrap.getBorderWidth('tb') + me.triggerWrap.getBorderWidth('tb'); height = Math.min(Math.max(height, me.growMin), me.growMax); me.bodyEl.setHeight(height); me.updateLayout(); me.fireEvent('autosize', me, height); } }, beforeDestroy: function() { var task = this.pasteTask; if (task) { task.cancel(); this.pasteTask = null; } this.callParent(); } }); 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' ], alias: 'widget.messagebox', OK: 1, YES: 2, NO: 4, CANCEL: 8, OKCANCEL: 9, YESNO: 6, YESNOCANCEL: 14, INFO: Ext.baseCSSPrefix + 'message-box-info', WARNING: Ext.baseCSSPrefix + 'message-box-warning', QUESTION: Ext.baseCSSPrefix + 'message-box-question', ERROR: Ext.baseCSSPrefix + 'message-box-error', hideMode: 'offsets', closeAction: 'hide', resizable: false, scrollable: true, title: ' ', defaultMinWidth: 250, defaultMaxWidth: 600, defaultMinHeight: 110, defaultMaxHeight: 500, minWidth: null, maxWidth: null, minHeight: null, maxHeight: null, constrain: true, cls: [ Ext.baseCSSPrefix + 'message-box', Ext.baseCSSPrefix + 'hidden-offsets' ], layout: { type: 'vbox', align: 'stretch' }, shrinkWrapDock: true, defaultTextHeight: 75, minProgressWidth: 250, minPromptWidth: 250, buttonText: { ok: 'OK', yes: 'Yes', no: 'No', cancel: 'Cancel' }, buttonIds: [ 'ok', 'yes', 'no', 'cancel' ], titleText: { confirm: 'Confirm', prompt: 'Prompt', wait: 'Loading...', alert: 'Attention' }, baseIconCls: Ext.baseCSSPrefix + 'message-box-icon', ariaRole: 'alertdialog', makeButton: function(btnIdx) { var btnId = this.buttonIds[btnIdx]; return new Ext.button.Button({ handler: this.btnCallback, itemId: btnId, scope: this, text: this.buttonText[btnId], minWidth: 75 }); }, btnCallback: function(btn, event) { var me = this, value, field; if (event && event.type === 'keydown' && !event.isSpecialKey()) { event.getTarget(null, null, true).on({ keyup: function(e) { me.btnCallback(btn, e); }, single: true }); return; } if (me.cfg.prompt || me.cfg.multiline) { if (me.cfg.multiline) { field = me.textArea; } else { field = me.textField; } value = field.getValue(); field.reset(); } me.hide(); me.userCallback(btn.itemId, value, me.cfg); }, hide: function() { var me = this, cls = me.cfg ? me.cfg.cls : ''; me.progressBar.reset(); if (cls) { me.removeCls(cls); } me.callParent(arguments); }, constructor: function(cfg) { var me = this; me.callParent(arguments); me.minWidth = me.defaultMinWidth = (me.minWidth || me.defaultMinWidth); me.maxWidth = me.defaultMaxWidth = (me.maxWidth || me.defaultMaxWidth); me.minHeight = me.defaultMinHeight = (me.minHeight || me.defaultMinHeight); me.maxHeight = me.defaultMaxHeight = (me.maxHeight || me.defaultMaxHeight); }, initComponent: function(cfg) { var me = this, baseId = me.id, i, button; me.title = me.title || ' '; me.iconCls = me.iconCls || ''; me.topContainer = new Ext.container.Container({ layout: 'hbox', padding: 10, style: { overflow: 'hidden' }, items: [ me.iconComponent = new Ext.Component({ cls: me.baseIconCls }), me.promptContainer = new Ext.container.Container({ flex: 1, layout: { type: 'vbox', align: 'stretch' }, items: [ me.msg = new Ext.Component({ id: baseId + '-msg', cls: me.baseCls + '-text' }), me.textField = new Ext.form.field.Text({ id: baseId + '-textfield', enableKeyEvents: true, listeners: { keydown: me.onPromptKey, scope: me } }), me.textArea = new Ext.form.field.TextArea({ id: baseId + '-textarea', height: 75 }) ] }) ] }); me.progressBar = new Ext.ProgressBar({ id: baseId + '-progressbar', margin: '0 10 10 10' }); me.items = [ me.topContainer, me.progressBar ]; me.msgButtons = []; for (i = 0; i < 4; i++) { button = me.makeButton(i); me.msgButtons[button.itemId] = button; me.msgButtons.push(button); } me.bottomTb = new Ext.toolbar.Toolbar({ id: baseId + '-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.on('close', me.onClose, me); me.callParent(); }, onClose: function() { var btn = this.header.child('[type=close]'); btn.itemId = 'cancel'; this.btnCallback(btn); delete btn.itemId; }, onPromptKey: function(textField, e) { var me = this; if (e.keyCode === e.RETURN || e.keyCode === 10) { if (me.msgButtons.ok.isVisible()) { me.msgButtons.ok.handler.call(me, me.msgButtons.ok); } else if (me.msgButtons.yes.isVisible()) { me.msgButtons.yes.handler.call(me, me.msgButtons.yes); } } }, reconfigure: function(cfg) { var me = this, buttons = 0, hideToolbar = true, oldButtonText = me.buttonText, resizer = me.resizer, header = me.header, headerCfg = header && !header.isHeader, message = cfg && (cfg.message || cfg.msg), resizeTracker, width, height, i, textArea, textField, msg, progressBar, msgButtons, wait; me.updateButtonText(); me.cfg = cfg = cfg || {}; wait = cfg.wait; if (cfg.width) { width = cfg.width; } if (cfg.height) { height = cfg.height; } me.minWidth = cfg.minWidth || me.defaultMinWidth; me.maxWidth = cfg.maxWidth || me.defaultMaxWidth; me.minHeight = cfg.minHeight || me.defaultMinHeight; me.maxHeight = cfg.maxHeight || me.defaultMaxHeight; if (resizer) { resizeTracker = resizer.resizeTracker; resizer.minWidth = resizeTracker.minWidth = me.minWidth; resizer.maxWidth = resizeTracker.maxWidth = me.maxWidth; resizer.minHeight = resizeTracker.minHeight = me.minHeight; resizer.maxHeight = resizeTracker.maxHeight = me.maxHeight; } delete me.defaultFocus; if (cfg.defaultFocus) { me.defaultFocus = cfg.defaultFocus; } me.animateTarget = cfg.animateTarget || undefined; me.modal = cfg.modal !== false; me.setTitle(cfg.title || (headerCfg && header.title) || me.title); me.setIconCls(cfg.iconCls || (headerCfg && header.iconCls) || me.iconCls); if (Ext.isObject(cfg.buttons)) { me.buttonText = cfg.buttons; buttons = 0; } else { me.buttonText = cfg.buttonText || me.buttonText; buttons = Ext.isNumber(cfg.buttons) ? cfg.buttons : 0; } buttons = buttons | me.updateButtonText(); me.buttonText = oldButtonText; Ext.suspendLayouts(); me.width = me.height = null; if (width || height) { if (width) { me.setWidth(width); } if (height) { me.setHeight(height); } } me.hidden = false; if (!me.rendered) { me.render(Ext.getBody()); } me.closable = cfg.closable !== false && !wait; header = me.header; if (header) { header.child('[type=close]').setVisible(me.closable); if (!cfg.title && !me.closable && !cfg.iconCls) { header.hide(); } else { header.show(); } } me.liveDrag = !cfg.proxyDrag; me.userCallback = Ext.Function.bindCallback(cfg.callback || cfg.fn || Ext.emptyFn, cfg.scope || Ext.global); me.setIcon(cfg.icon); msg = me.msg; if (message) { msg.setHtml(message); msg.show(); } else { msg.hide(); } textArea = me.textArea; textField = me.textField; if (cfg.prompt || cfg.multiline) { me.multiline = cfg.multiline; if (cfg.multiline) { textArea.setValue(cfg.value); textArea.setHeight(cfg.defaultTextHeight || me.defaultTextHeight); textArea.show(); textField.hide(); me.defaultFocus = textArea; } else { textField.setValue(cfg.value); textArea.hide(); textField.show(); me.defaultFocus = textField; } } else { textArea.hide(); textField.hide(); } progressBar = me.progressBar; if (cfg.progress || wait) { progressBar.show(); me.updateProgress(0, cfg.progressText); if (wait) { progressBar.wait(wait === true ? cfg.waitConfig : wait); } } else { progressBar.hide(); } msgButtons = me.msgButtons; for (i = 0; i < 4; i++) { if (buttons & Math.pow(2, i)) { if (!me.defaultFocus) { me.defaultFocus = msgButtons[i]; } msgButtons[i].show(); hideToolbar = false; } else { msgButtons[i].hide(); } } if (hideToolbar) { me.bottomTb.hide(); } else { me.bottomTb.show(); } Ext.resumeLayouts(true); }, updateButtonText: function() { var me = this, buttonText = me.buttonText, buttons = 0, btnId, btn; for (btnId in buttonText) { if (buttonText.hasOwnProperty(btnId)) { btn = me.msgButtons[btnId]; if (btn) { if (me.cfg && me.cfg.buttonText) { buttons = buttons | Math.pow(2, Ext.Array.indexOf(me.buttonIds, btnId)); } if (btn.text !== buttonText[btnId]) { btn.setText(buttonText[btnId]); } } } } return buttons; }, show: function(cfg) { var me = this, visibleFocusables; cfg = cfg || {}; if (Ext.Component.layoutSuspendCount) { Ext.on({ resumelayouts: function() { me.show(cfg); }, single: true }); return me; } me.reconfigure(cfg); if (cfg.cls) { me.addCls(cfg.cls); } visibleFocusables = me.query('textfield:not([hidden]),textarea:not([hidden]),button:not([hidden])'); me.preventFocusOnActivate = !visibleFocusables.length; me.hidden = true; me.callParent(); return me; }, onShow: function() { this.callParent(arguments); this.center(); }, updateText: function(text) { this.msg.setHtml(text); }, setIcon: function(icon, width, height) { var me = this, iconCmp = me.iconComponent, cls = me.messageIconCls; if (cls) { iconCmp.removeCls(cls); } if (icon) { iconCmp.show(); if (width || height) { iconCmp.setSize(width || iconCmp.getWidth(), height || iconCmp.getHeight()); } iconCmp.addCls(Ext.baseCSSPrefix + 'dlg-icon'); iconCmp.addCls(me.messageIconCls = icon); } else { iconCmp.removeCls(Ext.baseCSSPrefix + 'dlg-icon'); iconCmp.hide(); } return me; }, updateProgress: function(value, progressText, message) { this.progressBar.updateProgress(value, progressText); if (message) { this.updateText(message); } return this; }, onEsc: function() { if (this.closable !== false) { this.callParent(arguments); } }, confirm: function(cfg, message, fn, scope) { if (Ext.isString(cfg)) { cfg = { title: cfg, icon: this.QUESTION, message: message, buttons: this.YESNO, callback: fn, scope: scope }; } return this.show(cfg); }, prompt: function(title, message, fn, scope, multiline, value) { if (Ext.isString(title)) { title = { prompt: true, title: title, minWidth: this.minPromptWidth, message: message, buttons: this.OKCANCEL, callback: fn, scope: scope, multiline: multiline, value: value }; } return this.show(title); }, wait: function(message, title, config) { if (Ext.isString(message)) { message = { title: title, message: message, closable: false, wait: true, modal: true, minWidth: this.minProgressWidth, waitConfig: config }; } return this.show(message); }, alert: function(title, message, fn, scope) { if (Ext.isString(title)) { title = { title: title, message: message, buttons: this.OK, fn: fn, scope: scope, minWidth: this.minWidth }; } return this.show(title); }, progress: function(title, message, progressText) { if (Ext.isString(title)) { title = { title: title, message: message, progress: true, progressText: progressText }; } return this.show(title); } }, function(MessageBox) { Ext.onInternalReady(function() { Ext.MessageBox = Ext.Msg = new MessageBox(); }); }); 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.ErrorCollection', 'Ext.util.DelayedTask' ], taskDelay: 10, constructor: function(owner, config) { var me = this, reader; me.owner = owner; me.fieldMonitors = { validitychange: me.checkValidityDelay, enable: me.checkValidityDelay, disable: me.checkValidityDelay, dirtychange: me.checkDirtyDelay, errorchange: me.checkErrorDelay, scope: me }; me.checkValidityTask = new Ext.util.DelayedTask(me.checkValidity, me); me.checkDirtyTask = new Ext.util.DelayedTask(me.checkDirty, me); me.checkErrorTask = new Ext.util.DelayedTask(me.checkError, me); me.monitor = new Ext.container.Monitor({ selector: '[isFormField]:not([excludeForm])', scope: me, addHandler: me.onFieldAdd, removeHandler: me.onFieldRemove, invalidateHandler: me.onMonitorInvalidate }); me.monitor.bind(owner); Ext.apply(me, config); if (Ext.isString(me.paramOrder)) { me.paramOrder = me.paramOrder.split(/[\s,|]/); } reader = me.reader; if (reader && !reader.isReader) { if (typeof reader === 'string') { reader = { type: reader }; } me.reader = Ext.createByAlias('reader.' + reader.type, reader); } reader = me.errorReader; if (reader && !reader.isReader) { if (typeof reader === 'string') { reader = { type: reader }; } me.errorReader = Ext.createByAlias('reader.' + reader.type, reader); } me.callParent(); }, initialize: function() { this.initialized = true; this.onValidityChange(!this.hasInvalidField()); }, timeout: 30, paramsAsHash: false, waitTitle: 'Please Wait...', trackResetOnLoad: false, wasDirty: false, destroy: function() { var me = this, mon = me.monitor; if (mon) { mon.unbind(); me.monitor = null; } me.clearListeners(); me.checkValidityTask.cancel(); me.checkDirtyTask.cancel(); me.checkErrorTask.cancel(); me.checkValidityTask = me.checkDirtyTask = me.checkErrorTask = null; me.isDestroyed = true; }, onFieldAdd: function(field) { field.on(this.fieldMonitors); this.onMonitorInvalidate(); }, onFieldRemove: function(field) { field.un(this.fieldMonitors); this.onMonitorInvalidate(); }, onMonitorInvalidate: function() { if (this.initialized) { this.checkValidityDelay(); } }, getFields: function() { return this.monitor.getItems(); }, getBoundItems: function() { var boundItems = this._boundItems; if (!boundItems || boundItems.getCount() === 0) { boundItems = this._boundItems = new Ext.util.MixedCollection(); boundItems.addAll(this.owner.query('[formBind]')); } return boundItems; }, hasInvalidField: function() { return !!this.getFields().findBy(function(field) { var preventMark = field.preventMark, isValid; field.preventMark = true; isValid = field.isValid(); field.preventMark = preventMark; return !isValid; }); }, isValid: function() { var me = this, invalid; Ext.suspendLayouts(); invalid = me.getFields().filterBy(function(field) { return !field.validate(); }); Ext.resumeLayouts(true); return invalid.length < 1; }, checkValidity: function() { var me = this, valid; if (me.isDestroyed) { return; } valid = !me.hasInvalidField(); if (valid !== me.wasValid) { me.onValidityChange(valid); me.fireEvent('validitychange', me, valid); me.wasValid = valid; } }, checkValidityDelay: function() { var timer = this.taskDelay; if (timer) { this.checkValidityTask.delay(timer); } else { this.checkValidity(); } }, checkError: function() { this.fireEvent('errorchange', this); }, checkErrorDelay: function() { var timer = this.taskDelay; if (timer) { this.checkErrorTask.delay(timer); } else { this.checkError(); } }, onValidityChange: function(valid) { var boundItems = this.getBoundItems(), items, i, iLen, cmp; if (boundItems) { items = boundItems.items; iLen = items.length; for (i = 0; i < iLen; i++) { cmp = items[i]; if (cmp.disabled === valid) { cmp.setDisabled(!valid); } } } }, isDirty: function() { return !!this.getFields().findBy(function(f) { return f.isDirty(); }); }, checkDirtyDelay: function() { var timer = this.taskDelay; if (timer) { this.checkDirtyTask.delay(timer); } else { this.checkDirty(); } }, checkDirty: function() { var me = this, dirty; if (me.isDestroyed) { return; } dirty = this.isDirty(); if (dirty !== this.wasDirty) { this.fireEvent('dirtychange', this, dirty); this.wasDirty = dirty; } }, hasUpload: function() { return !!this.getFields().findBy(function(f) { return f.isFileUpload(); }); }, 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; }, submit: function(options) { options = options || {}; var me = this, action; if (options.standardSubmit || me.standardSubmit) { action = 'standardsubmit'; } else { action = me.api ? 'directsubmit' : 'submit'; } return me.doAction(action, options); }, load: function(options) { return this.doAction(this.api ? 'directload' : 'load', options); }, updateRecord: function(record) { record = record || this._record; if (!record) { Ext.Error.raise("A record is required."); return this; } var fields = record.self.fields, values = this.getFieldValues(), obj = {}, i = 0, len = fields.length, name; for (; i < len; ++i) { name = fields[i].name; if (values.hasOwnProperty(name)) { obj[name] = values[name]; } } record.beginEdit(); record.set(obj); record.endEdit(); return this; }, loadRecord: function(record) { this._record = record; return this.setValues(record.getData()); }, getRecord: function() { return this._record; }, beforeAction: function(action) { var me = this, waitMsg = action.waitMsg, maskCls = Ext.baseCSSPrefix + 'mask-loading', fields = me.getFields().items, f, fLen = fields.length, field, waitMsgTarget; for (f = 0; f < fLen; f++) { field = fields[f]; if (field.isFormField && field.syncValue) { field.syncValue(); } } if (waitMsg) { waitMsgTarget = me.waitMsgTarget; if (waitMsgTarget === true) { me.owner.el.mask(waitMsg, maskCls); } else if (waitMsgTarget) { waitMsgTarget = me.waitMsgTarget = Ext.get(waitMsgTarget); waitMsgTarget.mask(waitMsg, maskCls); } else { me.floatingAncestor = me.owner.up('[floating]'); if (me.floatingAncestor) { me.savePreventFocusOnActivate = me.floatingAncestor.preventFocusOnActivate; me.floatingAncestor.preventFocusOnActivate = true; } Ext.MessageBox.wait(waitMsg, action.waitTitle || me.waitTitle); } } }, afterAction: function(action, success) { var me = this; if (action.waitMsg) { var messageBox = Ext.MessageBox, waitMsgTarget = me.waitMsgTarget; if (waitMsgTarget === true) { me.owner.el.unmask(); } else if (waitMsgTarget) { waitMsgTarget.unmask(); } else { messageBox.hide(); } } if (me.floatingAncestor) { me.floatingAncestor.preventFocusOnActivate = me.savePreventFocusOnActivate; } if (success) { if (action.reset) { me.reset(); } Ext.callback(action.success, action.scope || action, [ me, action ]); me.fireEvent('actioncomplete', me, action); } else { Ext.callback(action.failure, action.scope || action, [ me, action ]); me.fireEvent('actionfailed', me, action); } }, findField: function(id) { return this.getFields().findBy(function(f) { return f.id === id || f.name === id || f.dataIndex === id; }); }, markInvalid: function(errors) { var me = this, e, eLen, error, value, key; function mark(fieldId, msg) { var field = me.findField(fieldId); if (field) { field.markInvalid(msg); } } if (Ext.isArray(errors)) { eLen = errors.length; for (e = 0; e < eLen; e++) { error = errors[e]; mark(error.id || error.field, error.msg || error.message); } } else if (errors instanceof Ext.data.ErrorCollection) { eLen = errors.items.length; for (e = 0; e < eLen; e++) { error = errors.items[e]; mark(error.field, error.message); } } else { for (key in errors) { if (errors.hasOwnProperty(key)) { value = errors[key]; mark(key, value, errors); } } } return this; }, setValues: function(values) { var me = this, v, vLen, val; function setVal(fieldId, val) { var field = me.findField(fieldId); if (field) { field.setValue(val); if (me.trackResetOnLoad) { field.resetOriginalValue(); } } } Ext.suspendLayouts(); if (Ext.isArray(values)) { vLen = values.length; for (v = 0; v < vLen; v++) { val = values[v]; setVal(val.id, val.value); } } else { Ext.iterate(values, setVal); } Ext.resumeLayouts(true); return this; }, getValues: function(asString, dirtyOnly, includeEmptyText, useDataValues, isSubmitting) { var values = {}, fields = this.getFields().items, fLen = fields.length, isArray = Ext.isArray, field, data, val, bucket, name, f; for (f = 0; f < fLen; f++) { field = fields[f]; if (!dirtyOnly || field.isDirty()) { data = field[useDataValues ? 'getModelData' : 'getSubmitData'](includeEmptyText, isSubmitting); if (Ext.isObject(data)) { for (name in data) { if (data.hasOwnProperty(name)) { val = data[name]; if (includeEmptyText && val === '') { val = field.emptyText || ''; } if (!field.isRadio) { if (values.hasOwnProperty(name)) { bucket = values[name]; if (!isArray(bucket)) { bucket = values[name] = [ bucket ]; } if (isArray(val)) { values[name] = bucket.concat(val); } else { bucket.push(val); } } else { values[name] = val; } } else { values[name] = values[name] || val; } } } } } } if (asString) { values = Ext.Object.toQueryString(values); } return values; }, getFieldValues: function(dirtyOnly) { return this.getValues(false, dirtyOnly, false, true); }, clearInvalid: function() { Ext.suspendLayouts(); var me = this, fields = me.getFields().items, f, fLen = fields.length; for (f = 0; f < fLen; f++) { fields[f].clearInvalid(); } Ext.resumeLayouts(true); return me; }, reset: function(resetRecord) { Ext.suspendLayouts(); var me = this, fields = me.getFields().items, f, fLen = fields.length; for (f = 0; f < fLen; f++) { fields[f].reset(); } Ext.resumeLayouts(true); if (resetRecord === true) { delete me._record; } return me; }, applyToFields: function(obj) { var fields = this.getFields().items, f, fLen = fields.length; for (f = 0; f < fLen; f++) { Ext.apply(fields[f], obj); } return this; }, applyIfToFields: function(obj) { var fields = this.getFields().items, f, fLen = fields.length; for (f = 0; f < fLen; f++) { Ext.applyIf(fields[f], obj); } return this; } }); Ext.define('Ext.form.FieldAncestor', { extend: 'Ext.Mixin', requires: [ 'Ext.container.Monitor' ], mixinConfig: { id: 'fieldAncestor', after: { initInheritedState: 'initFieldInheritedState' }, before: { destroy: 'onBeforeDestroy' } }, initFieldAncestor: function() { var me = this; me.monitor = new Ext.container.Monitor({ scope: me, selector: '[isFormField]:not([excludeForm])', addHandler: me.onChildFieldAdd, removeHandler: me.onChildFieldRemove }); me.initFieldDefaults(); }, initMonitor: function() { this.monitor.bind(this); }, initFieldInheritedState: function(inheritedState) { var inheritedFieldDefaults = inheritedState.fieldDefaults, fieldDefaults = this.fieldDefaults; if (fieldDefaults) { if (inheritedFieldDefaults) { inheritedState.fieldDefaults = Ext.apply(Ext.Object.chain(inheritedFieldDefaults), fieldDefaults); } else { inheritedState.fieldDefaults = fieldDefaults; } } }, onChildFieldAdd: function(field) { var me = this; me.mon(field, 'errorchange', me.handleFieldErrorChange, me); me.mon(field, 'validitychange', me.handleFieldValidityChange, me); }, onChildFieldRemove: function(field) { var me = this; me.mun(field, 'errorchange', me.handleFieldErrorChange, me); me.mun(field, 'validitychange', me.handleFieldValidityChange, me); }, initFieldDefaults: function() { if (!this.fieldDefaults) { this.fieldDefaults = {}; } }, handleFieldValidityChange: function(field, isValid) { var me = this; if (field !== me) { me.fireEvent('fieldvaliditychange', me, field, isValid); me.onFieldValidityChange(field, isValid); } }, handleFieldErrorChange: function(labelable, activeError) { var me = this; if (labelable !== me) { me.fireEvent('fielderrorchange', me, labelable, activeError); me.onFieldErrorChange(labelable, activeError); } }, onFieldValidityChange: Ext.emptyFn, onFieldErrorChange: Ext.emptyFn, onBeforeDestroy: function() { this.monitor.unbind(); } }); Ext.define('Ext.layout.component.field.FieldContainer', { extend: 'Ext.layout.component.Auto', alias: 'layout.fieldcontainer', type: 'fieldcontainer', waitForOuterHeightInDom: true, waitForOuterWidthInDom: true, beginLayout: function(ownerContext) { var containerEl = this.owner.containerEl; this.callParent(arguments); ownerContext.hasRawContent = true; containerEl.setStyle('width', ''); containerEl.setStyle('height', ''); ownerContext.containerElContext = ownerContext.getEl('containerEl'); }, measureContentHeight: function(ownerContext) { return ownerContext.hasDomProp('containerLayoutDone') ? this.callParent(arguments) : NaN; }, measureContentWidth: function(ownerContext) { return ownerContext.hasDomProp('containerLayoutDone') ? this.callParent(arguments) : NaN; }, publishInnerHeight: function(ownerContext, height) { var owner = this.owner; if (owner.labelAlign === 'top' && owner.hasVisibleLabel()) { height -= owner.labelEl.getHeight(); } if (owner.msgTarget === 'under' && owner.hasActiveError()) { height -= owner.errorWrapEl.getHeight(); } height -= owner.bodyEl.getPadding('tb'); ownerContext.containerElContext.setHeight(height); }, publishInnerWidth: function(ownerContext, width) { var owner = this.owner; if (owner.labelAlign !== 'top' && owner.hasVisibleLabel()) { width -= (owner.labelWidth + (owner.labelPad || 0)); } if (owner.msgTarget === 'side' && owner.hasActiveError()) { width -= owner.errorWrapEl.getWidth(); } width -= owner.bodyEl.getPadding('lr'); ownerContext.containerElContext.setWidth(width); } }); Ext.define('Ext.form.FieldContainer', { extend: 'Ext.container.Container', mixins: { labelable: 'Ext.form.Labelable', fieldAncestor: 'Ext.form.FieldAncestor' }, requires: 'Ext.layout.component.field.FieldContainer', alias: 'widget.fieldcontainer', componentLayout: 'fieldcontainer', componentCls: Ext.baseCSSPrefix + 'form-fieldcontainer', shrinkWrap: true, childEls: [ 'containerEl' ], combineLabels: false, labelConnector: ', ', combineErrors: false, maskOnDisable: false, invalidCls: '', fieldSubTpl: [ '' ], initComponent: function() { var me = this; me.initLabelable(); me.initFieldAncestor(); me.callParent(); me.initMonitor(); }, onAdd: function(labelItem) { var me = this; if (labelItem.isLabelable && Ext.isGecko && me.layout.type === 'absolute' && !me.hideLabel && me.labelAlign !== 'top') { labelItem.x += (me.labelWidth + me.labelPad); } me.callParent(arguments); if (labelItem.isLabelable && me.combineLabels) { labelItem.oldHideLabel = labelItem.hideLabel; labelItem.hideLabel = true; } me.updateLabel(); }, onRemove: function(labelItem, isDestroying) { var me = this; me.callParent(arguments); if (!isDestroying) { if (labelItem.isLabelable && me.combineLabels) { labelItem.hideLabel = labelItem.oldHideLabel; } me.updateLabel(); } }, initRenderData: function() { var me = this, data = me.callParent(); data.containerElCls = me.containerElCls; return Ext.applyIf(data, me.getLabelableRenderData()); }, 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); } return label; }, getSubTplData: function() { var ret = this.initRenderData(); Ext.apply(ret, this.subTplData); return ret; }, getSubTplMarkup: function(fieldData) { var me = this, tpl = me.getTpl('fieldSubTpl'), html; if (!tpl.renderContent) { me.setupRenderTpl(tpl); } html = tpl.apply(me.getSubTplData(fieldData)); return html; }, updateLabel: function() { var me = this, label = me.labelEl; if (label) { me.setFieldLabel(me.getFieldLabel()); } }, onFieldErrorChange: function() { 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); if (newErrors) { me.setActiveErrors(newErrors); } else { me.unsetActiveError(); } if (oldError !== me.getActiveError()) { me.updateLayout(); } } }, getCombinedErrors: function(invalidFields) { var errors = [], f, fLen = invalidFields.length, field, activeErrors, a, aLen, error, label; for (f = 0; f < fLen; f++) { field = invalidFields[f]; activeErrors = field.getActiveErrors(); aLen = activeErrors.length; for (a = 0; a < aLen; a++) { error = activeErrors[a]; label = field.getFieldLabel(); errors.push((label ? label + ': ' : '') + error); } } return errors; }, privates: { applyTargetCls: function(targetCls) { var containerElCls = this.containerElCls; this.containerElCls = containerElCls ? containerElCls + ' ' + targetCls : targetCls; }, getTargetEl: function() { return this.containerEl; }, initRenderTpl: function() { var me = this; if (!me.hasOwnProperty('renderTpl')) { me.renderTpl = me.getTpl('labelableRenderTpl'); } return me.callParent(); } } }); Ext.define('Ext.layout.container.CheckboxGroup', { extend: 'Ext.layout.container.Container', alias: [ 'layout.checkboxgroup' ], autoFlex: true, type: 'checkboxgroup', createsInnerCt: true, childEls: [ 'innerCt' ], renderTpl: [ '', '', '', '', '
' ], lastOwnerItemsGeneration: null, beginLayout: function(ownerContext) { var me = this, columns, numCols, i, width, cwidth, totalFlex = 0, flexedCols = 0, autoFlex = me.autoFlex, innerCtStyle = me.innerCt.dom.style; me.callParent(arguments); columns = me.columnNodes; ownerContext.innerCtContext = ownerContext.getEl('innerCt', me); if (!ownerContext.widthModel.shrinkWrap) { numCols = columns.length; if (me.columnsArray) { for (i = 0; i < numCols; i++) { width = me.owner.columns[i]; if (width < 1) { totalFlex += width; flexedCols++; } } for (i = 0; i < numCols; i++) { width = me.owner.columns[i]; if (width < 1) { cwidth = ((width / totalFlex) * 100) + '%'; } else { cwidth = width + 'px'; } columns[i].style.width = cwidth; } } else { for (i = 0; i < numCols; i++) { cwidth = autoFlex ? (1 / numCols * 100) + '%' : ''; columns[i].style.width = cwidth; flexedCols++; } } if (!flexedCols) { innerCtStyle.tableLayout = 'fixed'; innerCtStyle.width = ''; } else if (flexedCols < numCols) { innerCtStyle.tableLayout = 'fixed'; innerCtStyle.width = '100%'; } else { innerCtStyle.tableLayout = 'auto'; if (autoFlex) { innerCtStyle.width = '100%'; } else { innerCtStyle.width = ''; } } } else { innerCtStyle.tableLayout = 'auto'; innerCtStyle.width = ''; } }, cacheElements: function() { var me = this; me.callParent(); me.rowEl = me.innerCt.down('tr'); me.columnNodes = me.rowEl.dom.childNodes; }, calculate: function(ownerContext) { var me = this, targetContext, widthShrinkWrap, heightShrinkWrap, shrinkWrap, table, targetPadding; if (!ownerContext.getDomProp('containerChildrenSizeDone')) { me.done = false; } else { targetContext = ownerContext.innerCtContext; widthShrinkWrap = ownerContext.widthModel.shrinkWrap; heightShrinkWrap = ownerContext.heightModel.shrinkWrap; shrinkWrap = heightShrinkWrap || widthShrinkWrap; table = targetContext.el.dom; targetPadding = shrinkWrap && targetContext.getPaddingInfo(); if (widthShrinkWrap) { ownerContext.setContentWidth(table.offsetWidth + targetPadding.width, true); } if (heightShrinkWrap) { ownerContext.setContentHeight(table.offsetHeight + targetPadding.height, true); } } }, doRenderColumn: function(out, renderData, columnIndex) { var me = renderData.$layout, owner = me.owner, columnCount = renderData.columnCount, items = owner.items.items, itemCount = items.length, item, itemIndex, rowCount, increment, tree; if (owner.vertical) { rowCount = Math.ceil(itemCount / columnCount); itemIndex = columnIndex * rowCount; itemCount = Math.min(itemCount, itemIndex + rowCount); increment = 1; } else { itemIndex = columnIndex; increment = columnCount; } for (; itemIndex < itemCount; itemIndex += increment) { item = items[itemIndex]; me.configureItem(item); tree = item.getRenderTree(); Ext.DomHelper.generateMarkup(tree, out); } }, getColumnCount: function() { var me = this, owner = me.owner, ownerColumns = owner.columns; if (me.columnsArray) { return ownerColumns.length; } if (Ext.isNumber(ownerColumns)) { return ownerColumns; } return owner.items.length; }, getItemSizePolicy: function(item) { return this.autoSizePolicy; }, getRenderData: function() { var me = this, data = me.callParent(), owner = me.owner, i, columns = me.getColumnCount(), width, column, cwidth, autoFlex = me.autoFlex, totalFlex = 0, flexedCols = 0; if (me.columnsArray) { for (i = 0; i < columns; i++) { width = me.owner.columns[i]; if (width < 1) { totalFlex += width; flexedCols++; } } } data.colCls = owner.groupCls; data.columnCount = columns; data.columns = []; for (i = 0; i < columns; i++) { column = (data.columns[i] = {}); if (me.columnsArray) { width = me.owner.columns[i]; if (width < 1) { cwidth = ((width / totalFlex) * 100) + '%'; } else { cwidth = width + 'px'; } column.style = 'width:' + cwidth; } else { column.style = 'width:' + (1 / columns * 100) + '%'; flexedCols++; } } data.tableStyle = !flexedCols ? 'table-layout:fixed;' : (flexedCols < columns) ? 'table-layout:fixed;width:100%' : (autoFlex) ? 'table-layout:auto;width:100%' : 'table-layout:auto;'; return data; }, initLayout: function() { var me = this, owner = me.owner; me.columnsArray = Ext.isArray(owner.columns); me.autoColumns = !owner.columns || owner.columns === 'auto'; me.vertical = owner.vertical; me.callParent(); }, isValidParent: Ext.returnTrue, setupRenderTpl: function(renderTpl) { this.callParent(arguments); renderTpl.renderColumn = this.doRenderColumn; }, renderChildren: function() { var me = this, generation = me.owner.items.generation; if (me.lastOwnerItemsGeneration !== generation) { me.lastOwnerItemsGeneration = generation; me.renderItems(me.getLayoutItems()); } }, renderItems: function(items) { var me = this, itemCount = items.length, i, item, rowCount, columnCount, rowIndex, columnIndex; if (itemCount) { Ext.suspendLayouts(); if (me.autoColumns) { me.addMissingColumns(itemCount); } columnCount = me.columnNodes.length; rowCount = Math.ceil(itemCount / columnCount); for (i = 0; i < itemCount; i++) { item = items[i]; rowIndex = me.getRenderRowIndex(i, rowCount, columnCount); columnIndex = me.getRenderColumnIndex(i, rowCount, columnCount); if (!item.rendered) { me.renderItem(item, rowIndex, columnIndex); } else if (!me.isItemAtPosition(item, rowIndex, columnIndex)) { me.moveItem(item, rowIndex, columnIndex); } } if (me.autoColumns) { me.removeExceedingColumns(itemCount); } Ext.resumeLayouts(true); } }, isItemAtPosition: function(item, rowIndex, columnIndex) { return item.el.dom === this.getNodeAt(rowIndex, columnIndex); }, getRenderColumnIndex: function(itemIndex, rowCount, columnCount) { if (this.vertical) { return Math.floor(itemIndex / rowCount); } else { return itemIndex % columnCount; } }, getRenderRowIndex: function(itemIndex, rowCount, columnCount) { var me = this; if (me.vertical) { return itemIndex % rowCount; } else { return Math.floor(itemIndex / columnCount); } }, getNodeAt: function(rowIndex, columnIndex) { return this.columnNodes[columnIndex].childNodes[rowIndex]; }, addMissingColumns: function(itemsCount) { var me = this, existingColumnsCount = me.columnNodes.length, missingColumnsCount, row, cls, i; if (existingColumnsCount < itemsCount) { missingColumnsCount = itemsCount - existingColumnsCount; row = me.rowEl; cls = me.owner.groupCls; for (i = 0; i < missingColumnsCount; i++) { row.createChild({ cls: cls, tag: 'td', vAlign: 'top', role: 'presentation' }); } } }, removeExceedingColumns: function(itemsCount) { var me = this, existingColumnsCount = me.columnNodes.length, exceedingColumnsCount, row, i; if (existingColumnsCount > itemsCount) { exceedingColumnsCount = existingColumnsCount - itemsCount; row = me.rowEl; for (i = 0; i < exceedingColumnsCount; i++) { row.last().destroy(); } } }, renderItem: function(item, rowIndex, columnIndex) { var me = this; me.configureItem(item); item.render(Ext.get(me.columnNodes[columnIndex]), rowIndex); }, moveItem: function(item, rowIndex, columnIndex) { var me = this, column = me.columnNodes[columnIndex], targetNode = column.childNodes[rowIndex]; column.insertBefore(item.el.dom, targetNode || null); } }); 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.Checkbox', 'Ext.form.field.Base' ], columns: 'auto', vertical: false, allowBlank: true, blankText: "You must select at least one item in this group", defaultType: 'checkboxfield', groupCls: Ext.baseCSSPrefix + 'form-check-group', extraFieldBodyCls: Ext.baseCSSPrefix + 'form-checkboxgroup-body', layout: 'checkboxgroup', componentCls: Ext.baseCSSPrefix + 'form-checkboxgroup', ariaRole: 'group', initComponent: function() { var me = this; me.callParent(); me.initField(); }, initValue: function() { var me = this, valueCfg = me.value; me.originalValue = me.lastValue = valueCfg || me.getValue(); if (valueCfg) { me.setValue(valueCfg); } }, onAdd: function(field) { var me = this, items, len, i; if (field.isCheckbox) { me.mon(field, 'change', me.checkChange, me); } else if (field.isContainer) { items = field.items.items; for (i = 0 , len = items.length; i < len; i++) { me.onAdd(items[i]); } } me.callParent(arguments); }, onRemove: function(item) { var me = this, items, len, i; if (item.isCheckbox) { me.mun(item, 'change', me.checkChange, me); } else if (item.isContainer) { items = item.items.items; for (i = 0 , len = items.length; i < len; i++) { me.onRemove(items[i]); } } me.callParent(arguments); }, isEqual: function(value1, value2) { var toQueryString = Ext.Object.toQueryString; return toQueryString(value1) === toQueryString(value2); }, getErrors: function() { var errors = []; if (!this.allowBlank && Ext.isEmpty(this.getChecked())) { errors.push(this.blankText); } return errors; }, getBoxes: function(query) { return this.query('[isCheckbox]' + (query || '')); }, eachBox: function(fn, scope) { Ext.Array.forEach(this.getBoxes(), fn, scope || this); }, getChecked: function() { return this.getBoxes('[checked]'); }, isDirty: function() { var boxes = this.getBoxes(), b, bLen = boxes.length; for (b = 0; b < bLen; b++) { if (boxes[b].isDirty()) { return true; } } }, setReadOnly: function(readOnly) { var boxes = this.getBoxes(), b, bLen = boxes.length; for (b = 0; b < bLen; b++) { boxes[b].setReadOnly(readOnly); } this.readOnly = readOnly; }, reset: function() { var me = this, hadError = me.hasActiveError(), preventMark = me.preventMark; me.preventMark = true; me.batchChanges(function() { var boxes = me.getBoxes(), b, bLen = boxes.length; for (b = 0; b < bLen; b++) { boxes[b].reset(); } }); me.preventMark = preventMark; me.unsetActiveError(); if (hadError) { me.updateLayout(); } }, resetOriginalValue: function() { var me = this, boxes = me.getBoxes(), b, bLen = boxes.length; for (b = 0; b < bLen; b++) { boxes[b].resetOriginalValue(); } me.originalValue = me.getValue(); me.checkDirty(); }, setValue: function(value) { var me = this, boxes = me.getBoxes(), b, bLen = boxes.length, box, name, cbValue; me.batchChanges(function() { Ext.suspendLayouts(); for (b = 0; b < bLen; b++) { box = boxes[b]; name = box.getName(); cbValue = false; if (value) { if (Ext.isArray(value[name])) { cbValue = Ext.Array.contains(value[name], box.inputValue); } else { cbValue = value[name]; } } box.setValue(cbValue); } Ext.resumeLayouts(true); }); return me; }, getValue: function() { var values = {}, boxes = this.getBoxes(), b, bLen = boxes.length, box, name, inputValue, bucket; for (b = 0; b < bLen; b++) { box = boxes[b]; name = box.getName(); inputValue = box.inputValue; if (box.getValue()) { if (values.hasOwnProperty(name)) { bucket = values[name]; if (!Ext.isArray(bucket)) { bucket = values[name] = [ bucket ]; } bucket.push(inputValue); } else { values[name] = inputValue; } } } return values; }, getSubmitData: function() { return null; }, getModelData: function() { return null; }, validate: function() { var me = this, errors, isValid, wasValid; if (me.disabled) { isValid = true; } else { errors = me.getErrors(); isValid = Ext.isEmpty(errors); wasValid = me.wasValid; if (isValid) { me.unsetActiveError(); } else { me.setActiveError(errors); } } if (isValid !== wasValid) { me.wasValid = isValid; me.fireEvent('validitychange', me, isValid); me.updateLayout(); } return isValid; } }, function() { this.borrow(Ext.form.field.Base, [ 'markInvalid', 'clearInvalid', 'setError' ]); }); Ext.define('Ext.form.FieldSet', { extend: 'Ext.container.Container', mixins: { fieldAncestor: 'Ext.form.FieldAncestor' }, alias: 'widget.fieldset', uses: [ 'Ext.form.field.Checkbox', 'Ext.panel.Tool', 'Ext.layout.container.Anchor', 'Ext.layout.component.FieldSet' ], focusable: true, checkboxUI: 'default', collapsed: false, toggleOnTitleClick: true, baseCls: Ext.baseCSSPrefix + 'fieldset', layout: 'anchor', componentLayout: 'fieldset', ariaRole: null, autoEl: 'fieldset', childEls: [ 'body' ], renderTpl: [ '{%this.renderLegend(out,values);%}', '
style="{bodyStyle}">', '{%this.renderContainer(out,values);%}', '
' ], stateEvents: [ 'collapse', 'expand' ], maskOnDisable: false, beforeDestroy: function() { var me = this, legend = me.legend; if (legend) { delete legend.ownerCt; legend.destroy(); me.legend = null; } me.callParent(); }, initComponent: function() { var me = this, baseCls = me.baseCls; me.initFieldAncestor(); me.callParent(); me.layout.managePadding = me.layout.manageOverflow = false; if (me.collapsed) { me.addCls(baseCls + '-collapsed'); me.collapse(); } if (me.title || me.checkboxToggle || me.collapsible) { me.addTitleClasses(); me.legend = Ext.widget(me.createLegendCt()); } me.initMonitor(); }, initRenderData: function() { var me = this, data = me.callParent(); data.bodyTargetCls = me.bodyTargetCls; me.protoBody.writeTo(data); delete me.protoBody; return data; }, getState: function() { var state = this.callParent(); state = this.addPropertyToState(state, 'collapsed'); return state; }, afterCollapse: Ext.emptyFn, afterExpand: Ext.emptyFn, collapsedHorizontal: function() { return true; }, collapsedVertical: function() { return true; }, createLegendCt: function() { var me = this, items = [], legend = { xtype: 'container', baseCls: me.baseCls + '-header', layout: 'container', ui: me.ui, id: me.id + '-legend', autoEl: 'legend', ariaRole: null, ariaLabelledBy: '.' + me.baseCls + '-header-text', items: items, ownerCt: me, shrinkWrap: true, ownerLayout: me.componentLayout }; if (me.checkboxToggle) { items.push(me.createCheckboxCmp()); } else if (me.collapsible) { items.push(me.createToggleCmp()); } items.push(me.createTitleCmp()); return legend; }, createTitleCmp: function() { var me = this, cfg = { xtype: 'component', html: me.title, ui: me.ui, cls: me.baseCls + '-header-text', id: me.id + '-legendTitle' }; if (me.collapsible && me.toggleOnTitleClick) { cfg.listeners = { click: { element: 'el', scope: me, fn: me.toggle } }; cfg.cls += ' ' + me.baseCls + '-header-text-collapsible'; } return (me.titleCmp = Ext.widget(cfg)); }, createCheckboxCmp: function() { var me = this, suffix = '-checkbox', cls = me.baseCls + '-header' + suffix; cls += ' ' + cls + '-' + me.ui; me.checkboxCmp = Ext.widget({ xtype: 'checkbox', hideEmptyLabel: true, name: me.checkboxName || me.id + suffix, cls: cls, id: me.id + '-legendChk', ui: me.checkboxUI, checked: !me.collapsed, msgTarget: 'none', listeners: { change: me.onCheckChange, scope: me } }); return me.checkboxCmp; }, createToggleCmp: function() { var me = this; me.toggleCmp = Ext.widget({ xtype: 'tool', cacheHeight: false, cls: me.baseCls + '-header-tool-' + me.ui, type: 'toggle', handler: me.toggle, id: me.id + '-legendToggle', scope: me }); return me.toggleCmp; }, doRenderLegend: function(out, renderData) { var me = renderData.$comp, legend = me.legend, tree; if (legend) { legend.ownerLayout.configureItem(legend); tree = legend.getRenderTree(); Ext.DomHelper.generateMarkup(tree, out); } }, getCollapsed: function() { return this.collapsed ? 'top' : false; }, getCollapsedDockedItems: function() { var legend = this.legend; return legend ? [ legend ] : []; }, setTitle: function(title) { var me = this, legend = me.legend; me.title = title; if (me.rendered) { if (!legend) { me.legend = legend = Ext.widget(me.createLegendCt()); me.addTitleClasses(); legend.ownerLayout.configureItem(legend); legend.render(me.el, 0); } me.titleCmp.update(title); } else if (legend) { me.titleCmp.update(title); } else { me.addTitleClasses(); me.legend = Ext.widget(me.createLegendCt()); } return me; }, addTitleClasses: function() { var me = this, title = me.title, baseCls = me.baseCls; if (title) { me.addCls(baseCls + '-with-title'); } if (title || me.checkboxToggle || me.collapsible) { me.addCls(baseCls + '-with-legend'); } }, expand: function() { return this.setExpanded(true); }, collapse: function() { return this.setExpanded(false); }, setExpanded: function(expanded) { var me = this, checkboxCmp = me.checkboxCmp, operation = expanded ? 'expand' : 'collapse'; if (!me.rendered || me.fireEvent('before' + operation, me) !== false) { expanded = !!expanded; if (checkboxCmp) { checkboxCmp.setValue(expanded); } if (expanded) { me.removeCls(me.baseCls + '-collapsed'); } else { me.addCls(me.baseCls + '-collapsed'); } me.collapsed = !expanded; if (expanded) { delete me.getInherited().collapsed; } else { me.getInherited().collapsed = true; } if (me.rendered) { me.updateLayout({ isRoot: false }); me.fireEvent(operation, me); } } return me; }, 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)); } } return refItems; }, toggle: function() { this.setExpanded(!!this.collapsed); }, privates: { applyTargetCls: function(targetCls) { this.bodyTargetCls = targetCls; }, finishRender: function() { var legend = this.legend; this.callParent(); if (legend) { legend.finishRender(); } }, getProtoBody: function() { var me = this, body = me.protoBody; if (!body) { me.protoBody = body = new Ext.util.ProtoElement({ styleProp: 'bodyStyle', styleIsText: true }); } return body; }, getDefaultContentTarget: function() { return this.body; }, getTargetEl: function() { return this.body || this.frameBody || this.el; }, initPadding: function(targetEl) { var me = this, body = me.getProtoBody(), padding = me.padding, bodyPadding; if (padding !== undefined) { if (Ext.isIE8) { padding = me.parseBox(padding); bodyPadding = Ext.Element.parseBox(0); bodyPadding.top = padding.top; padding.top = 0; body.setStyle('padding', me.unitizeBox(bodyPadding)); } targetEl.setStyle('padding', me.unitizeBox(padding)); } }, onCheckChange: function(cmp, checked) { this.setExpanded(checked); }, setupRenderTpl: function(renderTpl) { this.callParent(arguments); renderTpl.renderLegend = this.doRenderLegend; } } }); Ext.define('Ext.form.Label', { extend: 'Ext.Component', alias: 'widget.label', requires: [ 'Ext.util.Format' ], autoEl: 'label', maskOnDisable: false, getElConfig: function() { var me = this; me.html = me.text ? Ext.util.Format.htmlEncode(me.text) : (me.html || ''); return Ext.apply(me.callParent(), { htmlFor: me.forId || '' }); }, 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; me.updateLayout(); } return me; } }); 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' ], layout: 'anchor', ariaRole: 'form', basicFormConfigs: [ 'api', 'baseParams', 'errorReader', 'jsonSubmit', 'method', 'paramOrder', 'paramsAsHash', 'reader', 'standardSubmit', 'timeout', 'trackResetOnLoad', 'url', 'waitMsgTarget', 'waitTitle' ], 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() { this.callParent(); this.initMonitor(); this.form = this.createForm(); }, afterFirstLayout: function() { this.callParent(arguments); this.form.initialize(); }, createForm: function() { var cfg = {}, props = this.basicFormConfigs, len = props.length, i = 0, prop; for (; i < len; ++i) { prop = props[i]; cfg[prop] = this[prop]; } return new Ext.form.Basic(this, cfg); }, getForm: function() { return this.form; }, loadRecord: function(record) { return this.getForm().loadRecord(record); }, getRecord: function() { return this.getForm().getRecord(); }, updateRecord: function(record) { return this.getForm().updateRecord(record); }, getValues: function(asString, dirtyOnly, includeEmptyText, useDataValues) { return this.getForm().getValues(asString, dirtyOnly, includeEmptyText, useDataValues); }, isDirty: function() { return this.form.isDirty(); }, isValid: function() { return this.form.isValid(); }, reset: function() { this.form.reset(); }, hasInvalidField: function() { return this.form.hasInvalidField(); }, beforeDestroy: function() { this.stopPolling(); this.form.destroy(); this.callParent(); }, load: function(options) { this.form.load(options); }, submit: function(options) { this.form.submit(options); }, startPolling: function(interval) { this.stopPolling(); var task = new Ext.util.TaskRunner(interval); task.start({ interval: 0, run: this.checkChange, scope: this }); this.pollTask = task; }, stopPolling: function() { var task = this.pollTask; if (task) { task.stopAll(); delete this.pollTask; } }, checkChange: function() { var fields = this.form.getFields().items, f, fLen = fields.length; for (f = 0; f < fLen; f++) { fields[f].checkChange(); } } }); Ext.define('Ext.form.RadioManager', { extend: 'Ext.util.MixedCollection', singleton: true, getByName: function(name, formId) { return this.filterBy(function(item) { return item.name === name && item.getFormId() === formId; }); }, getWithValue: function(name, value, formId) { return this.filterBy(function(item) { return item.name === name && item.inputValue == value && item.getFormId() === formId; }); }, getChecked: function(name, formId) { return this.findBy(function(item) { return item.name === name && item.checked && item.getFormId() === formId; }); } }); 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, inputType: 'radio', ariaRole: 'radio', tabIndex: 0, formId: null, getGroupValue: function() { var selected = this.getManager().getChecked(this.name, this.getFormId()); return selected ? selected.inputValue : null; }, onBoxClick: function() { var me = this; if (!me.disabled && !me.readOnly) { this.setValue(true); } }, onRemoved: function() { this.callParent(arguments); this.formId = null; }, setValue: function(value) { var me = this, active; if (Ext.isBoolean(value)) { me.callParent(arguments); } else { active = me.getManager().getWithValue(me.name, value, me.getFormId()).getAt(0); if (active) { active.setValue(true); } } return me; }, getSubmitValue: function() { return this.checked ? this.inputValue : null; }, getModelData: function() { var o = this.callParent(arguments); if (o) { o[this.getName()] = this.getSubmitValue(); } return o; }, onChange: function(newVal, oldVal) { var me = this, r, rLen, radio, radios; me.callParent(arguments); if (newVal) { radios = me.getManager().getByName(me.name, me.getFormId()).items; rLen = radios.length; for (r = 0; r < rLen; r++) { radio = radios[r]; if (radio !== me) { radio.setValue(false); } } } }, getManager: function() { return Ext.form.RadioManager; } }); Ext.define('Ext.form.RadioGroup', { extend: 'Ext.form.CheckboxGroup', alias: 'widget.radiogroup', requires: [ 'Ext.form.field.Radio' ], mixins: [ 'Ext.util.FocusableContainer' ], allowBlank: true, blankText: 'You must select one item in this group', defaultType: 'radiofield', groupCls: Ext.baseCSSPrefix + 'form-radio-group', ariaRole: 'radiogroup', getBoxes: function(query, root) { return (root || this).query('[isRadio]' + (query || '')); }, checkChange: function() { var value = this.getValue(), key = Ext.Object.getKeys(value)[0]; if (Ext.isArray(value[key])) { return; } this.callParent(arguments); }, setValue: function(value) { var cbValue, first, formId, radios, i, len, name; if (Ext.isObject(value)) { Ext.suspendLayouts(); first = this.items.first(); formId = first ? first.getFormId() : null; for (name in value) { cbValue = value[name]; radios = Ext.form.RadioManager.getWithValue(name, cbValue, formId).items; len = radios.length; for (i = 0; i < len; ++i) { radios[i].setValue(true); } } Ext.resumeLayouts(true); } return this; }, privates: { getFocusables: function() { return this.getBoxes(); }, initDefaultFocusable: function(beforeRender) { var me = this, checked, item; checked = me.getChecked(); if (checked.length > 1) { Ext.log.error("RadioGroup " + me.id + " has more than one checked button"); } if (checked.length) { item = checked[0]; } else { item = me.findNextFocusableChild(null, true, null, beforeRender); } if (item) { me.activateFocusable(item); } return item; }, onFocusableContainerFocusLeave: function() { this.clearFocusables(); this.initDefaultFocusable(); }, doFocusableChildAdd: function(child) { var me = this, mixin = me.mixins.focusablecontainer, boxes, i, len; boxes = child.isContainer ? me.getBoxes('', child) : [ child ]; for (i = 0 , len = boxes.length; i < len; i++) { mixin.doFocusableChildAdd.call(me, boxes[i]); } }, doFocusableChildRemove: function(child) { var me = this, mixin = me.mixins.focusablecontainer, boxes, i, len; boxes = child.isContainer ? me.getBoxes('', child) : [ child ]; for (i = 0 , len = boxes.length; i < len; i++) { mixin.doFocusableChildRemove.call(me, boxes[i]); } }, focusChild: function(radio, forward, e) { var nextRadio = this.mixins.focusablecontainer.focusChild.apply(this, arguments); if (!e.ctrlKey) { nextRadio.setValue(true); } } } }); Ext.define('Ext.form.action.DirectAction', { extend: 'Ext.Mixin', mixinConfig: { id: 'directaction' }, resolveMethod: function(type) { var me = this, form = me.form, api = form.api, fn; if (!api) { Ext.Error.raise("Cannot resolve Ext.Direct API method for " + type + " action; form " + form.id + " has no api object defined"); } fn = api[type]; if (typeof fn !== 'function') { var fnName = fn; api[type] = fn = Ext.direct.Manager.parseMethod(fn); if (!Ext.isFunction(fn)) { Ext.Error.raise("Cannot resolve Ext.Direct API method " + fnName + " for " + type + " action"); } } return fn; } }); Ext.define('Ext.form.action.DirectLoad', { extend: 'Ext.form.action.Load', alternateClassName: 'Ext.form.Action.DirectLoad', alias: 'formaction.directload', requires: [ 'Ext.direct.Manager' ], mixins: [ 'Ext.form.action.DirectAction' ], type: 'directload', run: function() { var me = this, form = me.form, metadata = me.metadata || form.metadata, timeout = me.timeout || form.timeout, args, fn; fn = me.resolveMethod('load'); args = fn.directCfg.method.getArgs({ params: me.getParams(), paramOrder: form.paramOrder, paramsAsHash: form.paramsAsHash, options: timeout != null ? { timeout: timeout * 1000 } : null, metadata: metadata, callback: me.onComplete, scope: me }); fn.apply(window, args); }, processResponse: function(result) { return (this.result = result); }, onComplete: function(data) { if (data) { this.onSuccess(data); } else { this.onFailure(null); } } }); Ext.define('Ext.form.action.DirectSubmit', { extend: 'Ext.form.action.Submit', alternateClassName: 'Ext.form.Action.DirectSubmit', alias: 'formaction.directsubmit', requires: [ 'Ext.direct.Manager' ], mixins: [ 'Ext.form.action.DirectAction' ], type: 'directsubmit', doSubmit: function() { var me = this, form = me.form, metadata = me.metadata || form.metadata, timeout = me.timeout || form.timeout, fn, formInfo, args; fn = me.resolveMethod('submit'); formInfo = me.buildForm(); args = fn.directCfg.method.getArgs({ params: formInfo.formEl, options: timeout != null ? { timeout: timeout * 1000 } : null, metadata: metadata, callback: me.onComplete, scope: me }); fn.apply(window, args); me.cleanup(formInfo); }, processResponse: function(result) { return (this.result = result); }, onComplete: function(data) { if (data) { this.onSuccess(data); } else { this.onFailure(null); } } }); Ext.define('Ext.form.action.StandardSubmit', { extend: 'Ext.form.action.Submit', alias: 'formaction.standardsubmit', doSubmit: function() { var formInfo = this.buildForm(); formInfo.formEl.submit(); this.cleanup(formInfo); } }); Ext.define('Ext.form.field.Picker', { extend: 'Ext.form.field.Text', alias: 'widget.pickerfield', alternateClassName: 'Ext.form.Picker', requires: [ 'Ext.util.KeyNav' ], config: { triggers: { picker: { handler: 'onTriggerClick', scope: 'this' } } }, isPickerField: true, matchFieldWidth: true, pickerAlign: 'tl-bl?', openCls: Ext.baseCSSPrefix + 'pickerfield-open', isExpanded: false, editable: true, applyTriggers: function(triggers) { var me = this, picker = triggers.picker; if (!picker.cls) { picker.cls = me.triggerCls; } return me.callParent([ triggers ]); }, initEvents: function() { var me = this; me.callParent(); me.keyNav = new Ext.util.KeyNav(me.inputEl, { down: me.onDownArrow, esc: { handler: me.onEsc, scope: me, defaultEventAction: false }, scope: me, forceKeyDown: true }); if (!me.editable) { me.mon(me.inputEl, 'click', me.onTriggerClick, me); } if (Ext.isGecko) { me.inputEl.dom.setAttribute('autocomplete', 'off'); } }, onEsc: function(e) { if (Ext.isIE) { e.preventDefault(); } if (this.isExpanded) { this.collapse(); e.stopEvent(); } }, onDownArrow: function(e) { if (!this.isExpanded) { e.stopEvent(); this.onTriggerClick(); } }, expand: function() { var me = this, bodyEl, picker, doc, collapseIf; if (me.rendered && !me.isExpanded && !me.isDestroyed) { bodyEl = me.bodyEl; picker = me.getPicker(); doc = Ext.getDoc(); collapseIf = me.collapseIf; picker.setMaxHeight(picker.initialConfig.maxHeight); if (me.matchFieldWidth) { picker.width = me.bodyEl.getWidth(); } picker.show(); me.isExpanded = true; me.alignPicker(); bodyEl.addCls(me.openCls); me.hideListeners = doc.on({ mousewheel: me.collapseIf, touchstart: me.collapseIf, scope: me, delegated: false, destroyable: true }); Ext.on('resize', me.alignPicker, me, { buffer: 1 }); me.fireEvent('expand', me); me.onExpand(); } }, onExpand: Ext.emptyFn, alignPicker: function() { if (!this.isDestroyed) { var picker = this.getPicker(); if (picker.isVisible() && picker.isFloating()) { this.doAlign(); } } }, doAlign: function() { var me = this, picker = me.picker, aboveSfx = '-above', isAbove; me.picker.alignTo(me.triggerWrap, me.pickerAlign, me.pickerOffset); isAbove = picker.el.getY() < me.inputEl.getY(); me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls + aboveSfx); picker[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx); }, collapse: function() { var me = this; if (me.isExpanded && !me.isDestroyed && !me.destroying) { var openCls = me.openCls, picker = me.picker, aboveSfx = '-above'; picker.hide(); me.isExpanded = false; me.bodyEl.removeCls([ openCls, openCls + aboveSfx ]); picker.el.removeCls(picker.baseCls + aboveSfx); me.hideListeners.destroy(); Ext.un('resize', me.alignPicker, me); me.fireEvent('collapse', me); me.onCollapse(); } }, onCollapse: Ext.emptyFn, collapseIf: function(e) { var me = this; if (!me.isDestroyed && !e.within(me.bodyEl, false, true) && !me.owns(e.target) && !Ext.fly(e.target).isFocusable()) { me.collapse(); } }, getPicker: function() { var me = this, picker = me.picker; if (!picker) { me.creatingPicker = true; me.picker = picker = me.createPicker(); picker.ownerCmp = me; delete me.creatingPicker; } return me.picker; }, onFocusLeave: function(e) { var me = this; me.collapse(); me.callParent([ e ]); }, getRefItems: function() { var result = []; if (this.picker) { result[0] = this.picker; } return result; }, createPicker: Ext.emptyFn, onTriggerClick: function(e) { var me = this; if (!me.readOnly && !me.disabled) { if (me.isExpanded) { me.collapse(); } else { me.expand(); } } }, beforeDestroy: function() { var me = this, picker = me.picker; me.callParent(); Ext.un('resize', me.alignPicker, me); Ext.destroy(me.keyNav, picker); if (picker) { me.picker = picker.pickerField = null; } } }); Ext.define('Ext.view.BoundListKeyNav', { extend: 'Ext.view.NavigationModel', alias: 'view.navigation.boundlist', navigateOnSpace: true, initKeyNav: function(view) { var me = this, field = view.pickerField; if (!me.keyNav) { me.callParent([ view ]); me.keyNav.map.addBinding({ key: Ext.event.Event.ESC, fn: me.onKeyEsc, scope: me }); } if (!field) { return; } if (!field.rendered) { field.on('render', Ext.Function.bind(me.initKeyNav, me, [ view ], 0), me, { single: true }); return; } me.fieldKeyNav = new Ext.util.KeyNav({ disabled: true, target: field.inputEl, forceKeyDown: true, up: me.onKeyUp, down: me.onKeyDown, right: me.onKeyRight, left: me.onKeyLeft, pageDown: me.onKeyPageDown, pageUp: me.onKeyPageUp, home: me.onKeyHome, end: me.onKeyEnd, tab: me.onKeyTab, space: me.onKeySpace, enter: me.onKeyEnter, A: { ctrl: true, handler: me.onSelectAllKeyPress }, scope: me }); }, processViewEvent: function(view, record, node, index, event) { if (event.within(view.listWrap)) { return event; } if (event.getKey() === event.ESC) { if (Ext.fly(event.target).isInputField()) { event.target = event.target.parentNode; } return event; } }, enable: function() { this.fieldKeyNav.enable(); this.callParent(); }, disable: function() { this.fieldKeyNav.disable(); this.callParent(); }, onItemMouseDown: function(view, record, item, index, event) { this.callParent([ view, record, item, index, event ]); event.preventDefault(); }, onKeyUp: function() { var me = this, boundList = me.view, allItems = boundList.all, oldItem = boundList.highlightedItem, oldItemIdx = oldItem ? boundList.indexOf(oldItem) : -1, newItemIdx = oldItemIdx > 0 ? oldItemIdx - 1 : allItems.getCount() - 1; me.setPosition(newItemIdx); }, onKeyDown: function() { var me = this, boundList = me.view, allItems = boundList.all, oldItem = boundList.highlightedItem, oldItemIdx = oldItem ? boundList.indexOf(oldItem) : -1, newItemIdx = oldItemIdx < allItems.getCount() - 1 ? oldItemIdx + 1 : 0; me.setPosition(newItemIdx); }, onKeyLeft: Ext.returnTrue, onKeyRight: Ext.returnTrue, onKeyTab: function(e) { var view = this.view, field = view.pickerField; if (view.isVisible()) { if (field.selectOnTab) { this.selectHighlighted(e); } if (field.collapse) { field.collapse(); } } return true; }, onKeyEnter: function(e) { var view = this.view, selModel = view.getSelectionModel(), field = view.pickerField, count = selModel.getCount(); e.stopEvent(); this.selectHighlighted(e); if (!field.multiSelect && count === selModel.getCount() && field.collapse) { field.collapse(); } }, onKeySpace: function() { if (this.navigateOnSpace) { this.callParent(arguments); } return true; }, onKeyEsc: function() { if (this.view.pickerField) { this.view.pickerField.collapse(); } }, focusItem: function(item) { var me = this, boundList = me.view; if (typeof item === 'number') { item = boundList.all.item(item); } if (item) { item = item.dom; boundList.highlightItem(item); boundList.getScrollable().scrollIntoView(item, false); } }, selectHighlighted: function(e) { var me = this, boundList = me.view, selModel = boundList.getSelectionModel(), highlightedRec, highlightedPosition = me.recordIndex; if (boundList.all.getCount()) { highlightedRec = me.getRecord(); if (highlightedRec) { if (e.getKey() === e.ENTER || !selModel.isSelected(highlightedRec)) { selModel.selectWithEvent(highlightedRec, e); if (!boundList.store.data.contains(highlightedRec)) { me.setPosition(Math.min(highlightedPosition, boundList.store.getCount() - 1)); } } } } }, destroy: function() { Ext.destroy(this.fieldKeyNav); this.callParent(); } }); Ext.define('Ext.layout.component.BoundList', { extend: 'Ext.layout.component.Auto', alias: 'layout.boundlist', type: 'component', beginLayout: function(ownerContext) { var me = this, owner = me.owner, toolbar = owner.pagingToolbar; me.scrollPos = owner.listWrap.getScroll(); me.callParent(arguments); if (owner.floating) { ownerContext.savedXY = owner.getXY(); owner.setXY([ 0, -9999 ]); } if (toolbar) { ownerContext.toolbarContext = ownerContext.context.getCmp(toolbar); } ownerContext.listContext = ownerContext.getEl('listWrap'); }, beginLayoutCycle: function(ownerContext) { var owner = this.owner; this.callParent(arguments); if (ownerContext.heightModel.auto) { owner.el.setHeight('auto'); owner.listWrap.setHeight('auto'); } }, getLayoutItems: function() { var toolbar = this.owner.pagingToolbar; return toolbar ? [ toolbar ] : []; }, isValidParent: function() { return true; }, finishedLayout: function(ownerContext) { var me = this, xy = ownerContext.savedXY, owner = me.owner, listWrap = owner.listWrap, scrollPos = me.scrollPos; me.callParent(arguments); if (xy) { me.owner.setXY(xy); } listWrap.setScrollLeft(scrollPos.left); listWrap.setScrollTop(scrollPos.top); }, measureContentWidth: function(ownerContext) { return this.owner.listWrap.getWidth(); }, measureContentHeight: function(ownerContext) { return this.owner.listWrap.getHeight(); }, publishInnerHeight: function(ownerContext, height) { var toolbar = ownerContext.toolbarContext, toolbarHeight = 0; if (toolbar) { toolbarHeight = toolbar.getProp('height'); } if (toolbarHeight === undefined) { this.done = false; } else { ownerContext.listContext.setHeight(height - ownerContext.getFrameInfo().height - toolbarHeight); } }, calculateOwnerHeightFromContentHeight: function(ownerContext) { var height = this.callParent(arguments), toolbar = ownerContext.toolbarContext; if (toolbar) { height += toolbar.getProp('height'); } return height; } }); Ext.define('Ext.toolbar.Item', { extend: 'Ext.Component', requires: [ 'Ext.toolbar.Toolbar' ], alias: 'widget.tbitem', alternateClassName: 'Ext.Toolbar.Item', enable: Ext.emptyFn, disable: Ext.emptyFn, focus: Ext.emptyFn }); Ext.define('Ext.toolbar.TextItem', { extend: 'Ext.toolbar.Item', requires: [ 'Ext.toolbar.Toolbar', 'Ext.XTemplate' ], alias: 'widget.tbtext', alternateClassName: 'Ext.Toolbar.TextItem', text: '', baseCls: Ext.baseCSSPrefix + 'toolbar-text', ariaRole: null, beforeRender: function() { var text = this.text; this.callParent(); if (text) { this.html = text; } }, setText: function(text) { this.update(text); } }); Ext.define('Ext.form.trigger.Spinner', { extend: 'Ext.form.trigger.Trigger', alias: 'trigger.spinner', cls: Ext.baseCSSPrefix + 'form-trigger-spinner', spinnerCls: Ext.baseCSSPrefix + 'form-spinner', spinnerUpCls: Ext.baseCSSPrefix + 'form-spinner-up', spinnerDownCls: Ext.baseCSSPrefix + 'form-spinner-down', focusCls: Ext.baseCSSPrefix + 'form-spinner-focus', overCls: Ext.baseCSSPrefix + 'form-spinner-over', clickCls: Ext.baseCSSPrefix + 'form-spinner-click', focusFieldOnClick: true, vertical: true, bodyTpl: '' + '
' + '
' + '
' + '' + '
' + '
', destroy: function() { var me = this; if (me.spinnerEl) { me.spinnerEl.destroy(); me.spinnerEl = me.upEl = me.downEl = null; } me.callParent(); }, getBodyRenderData: function() { var me = this; return { vertical: me.vertical, upDisabledCls: me.upEnabled ? '' : (me.spinnerUpCls + '-disabled'), downDisabledCls: me.downEnabled ? '' : (me.spinnerDownCls + '-disabled'), spinnerCls: me.spinnerCls, spinnerUpCls: me.spinnerUpCls, spinnerDownCls: me.spinnerDownCls }; }, getStateEl: function() { return this.spinnerEl; }, onClick: function() { var me = this, args = arguments, e = me.clickRepeater ? args[1] : args[0], field = me.field; if (!field.readOnly && !field.disabled) { if (me.upEl.contains(e.target)) { Ext.callback(me.upHandler, me.scope, [ field, me, e ], 0, field); } else if (me.downEl.contains(e.target)) { Ext.callback(me.downHandler, me.scope, [ field, me, e ], 0, field); } } field.inputEl.focus(); }, onFieldRender: function() { var me = this, vertical = me.vertical, spinnerEl, elements; me.callParent(); spinnerEl = me.spinnerEl = me.el.select('.' + me.spinnerCls, true); elements = spinnerEl.elements; me.upEl = vertical ? elements[0] : elements[1]; me.downEl = vertical ? elements[1] : elements[0]; }, setUpEnabled: function(enabled) { this.upEl[enabled ? 'removeCls' : 'addCls'](this.spinnerUpCls + '-disabled'); }, setDownEnabled: function(enabled) { this.downEl[enabled ? 'removeCls' : 'addCls'](this.spinnerDownCls + '-disabled'); } }); Ext.define('Ext.form.field.Spinner', { extend: 'Ext.form.field.Text', alias: 'widget.spinnerfield', alternateClassName: 'Ext.form.Spinner', requires: [ 'Ext.form.trigger.Spinner', 'Ext.util.KeyNav' ], config: { triggers: { spinner: { type: 'spinner', upHandler: 'onSpinnerUpClick', downHandler: 'onSpinnerDownClick', scope: 'this' } } }, spinUpEnabled: true, spinDownEnabled: true, keyNavEnabled: true, mouseWheelEnabled: true, repeatTriggerClick: true, onSpinUp: Ext.emptyFn, onSpinDown: Ext.emptyFn, ariaRole: 'spinbutton', applyTriggers: function(triggers) { var me = this, spinnerTrigger = triggers.spinner; spinnerTrigger.upEnabled = me.spinUpEnabled; spinnerTrigger.downEnabled = me.spinDownEnabled; return me.callParent([ triggers ]); }, onRender: function() { var me = this, spinnerTrigger = me.getTrigger('spinner'); me.callParent(); if (me.keyNavEnabled) { me.spinnerKeyNav = new Ext.util.KeyNav(me.inputEl, { scope: me, up: me.spinUp, down: me.spinDown }); } if (me.mouseWheelEnabled) { me.mon(me.bodyEl, 'mousewheel', me.onMouseWheel, me); } me.spinUpEl = spinnerTrigger.upEl; me.spinDownEl = spinnerTrigger.downEl; }, onSpinnerUpClick: function() { this.spinUp(); }, onSpinnerDownClick: function() { this.spinDown(); }, spinUp: function() { var me = this; if (me.spinUpEnabled && !me.disabled) { me.fireEvent('spin', me, 'up'); me.fireEvent('spinup', me); me.onSpinUp(); } }, spinDown: function() { var me = this; if (me.spinDownEnabled && !me.disabled) { me.fireEvent('spin', me, 'down'); me.fireEvent('spindown', me); me.onSpinDown(); } }, setSpinUpEnabled: function(enabled) { var me = this, wasEnabled = me.spinUpEnabled; me.spinUpEnabled = enabled; if (wasEnabled !== enabled && me.rendered) { me.getTrigger('spinner').setUpEnabled(enabled); } }, setSpinDownEnabled: function(enabled) { var me = this, wasEnabled = me.spinDownEnabled; me.spinDownEnabled = enabled; if (wasEnabled !== enabled && me.rendered) { me.getTrigger('spinner').setDownEnabled(enabled); } }, 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(); } }, onDestroy: function() { Ext.destroyMembers(this, 'spinnerKeyNav'); this.callParent(); } }); Ext.define('Ext.form.field.Number', { extend: 'Ext.form.field.Spinner', alias: 'widget.numberfield', alternateClassName: [ 'Ext.form.NumberField', 'Ext.form.Number' ], allowExponential: true, allowDecimals: true, decimalSeparator: null, submitLocaleSeparator: true, decimalPrecision: 2, minValue: Number.NEGATIVE_INFINITY, maxValue: Number.MAX_VALUE, step: 1, minText: 'The minimum value for this field is {0}', maxText: 'The maximum value for this field is {0}', nanText: '{0} is not a valid number', negativeText: 'The value cannot be negative', baseChars: '0123456789', autoStripChars: false, initComponent: function() { var me = this; if (me.decimalSeparator === null) { me.decimalSeparator = Ext.util.Format.decimalSeparator; } me.callParent(); me.setMinValue(me.minValue); me.setMaxValue(me.maxValue); }, setValue: function(value) { var me = this, bind, valueBind; if (me.hasFocus) { bind = me.getBind(); valueBind = bind && bind.value; if (valueBind && valueBind.syncing && value === me.value) { return me; } } return me.callParent([ value ]); }, getErrors: function(value) { value = arguments.length > 0 ? value : this.processRawValue(this.getRawValue()); var me = this, errors = me.callParent([ value ]), format = Ext.String.format, num; if (value.length < 1) { return errors; } value = String(value).replace(me.decimalSeparator, '.'); if (isNaN(value)) { errors.push(format(me.nanText, value)); } num = me.parseValue(value); if (me.minValue === 0 && num < 0) { errors.push(this.negativeText); } else if (num < me.minValue) { errors.push(format(me.minText, me.minValue)); } if (num > me.maxValue) { errors.push(format(me.maxText, me.maxValue)); } return errors; }, rawToValue: function(rawValue) { var value = this.fixPrecision(this.parseValue(rawValue)); if (value === null) { value = rawValue || null; } return value; }, 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; }, getSubmitValue: function() { var me = this, value = me.callParent(); if (!me.submitLocaleSeparator) { value = value.replace(me.decimalSeparator, '.'); } return value; }, onChange: function() { this.toggleSpinners(); this.callParent(arguments); }, toggleSpinners: function() { var me = this, value = me.getValue(), valueIsNull = value === null, enabled; if (me.spinUpEnabled || me.spinUpDisabledByToggle) { enabled = valueIsNull || value < me.maxValue; me.setSpinUpEnabled(enabled, true); } if (me.spinDownEnabled || me.spinDownDisabledByToggle) { enabled = valueIsNull || value > me.minValue; me.setSpinDownEnabled(enabled, true); } }, setMinValue: function(value) { var me = this, allowed; me.minValue = Ext.Number.from(value, Number.NEGATIVE_INFINITY); me.toggleSpinners(); if (me.disableKeyFilter !== true) { allowed = me.baseChars + ''; if (me.allowExponential) { allowed += me.decimalSeparator + 'e+-'; } else { if (me.allowDecimals) { allowed += me.decimalSeparator; } if (me.minValue < 0) { allowed += '-'; } } allowed = Ext.String.escapeRegex(allowed); me.maskRe = new RegExp('[' + allowed + ']'); if (me.autoStripChars) { me.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi'); } } }, setMaxValue: function(value) { this.maxValue = Ext.Number.from(value, Number.MAX_VALUE); this.toggleSpinners(); }, parseValue: function(value) { value = parseFloat(String(value).replace(this.decimalSeparator, '.')); return isNaN(value) ? null : value; }, 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 parseFloat(Ext.Number.toFixed(parseFloat(value), precision)); }, onBlur: function(e) { var me = this, v = me.rawToValue(me.getRawValue()); if (!Ext.isEmpty(v)) { me.setValue(v); } me.callParent([ e ]); }, setSpinUpEnabled: function(enabled, internal) { this.callParent(arguments); if (!internal) { delete this.spinUpDisabledByToggle; } else { this.spinUpDisabledByToggle = !enabled; } }, onSpinUp: function() { var me = this; if (!me.readOnly) { me.setSpinValue(Ext.Number.constrain(me.getValue() + me.step, me.minValue, me.maxValue)); } }, setSpinDownEnabled: function(enabled, internal) { this.callParent(arguments); if (!internal) { delete this.spinDownDisabledByToggle; } else { this.spinDownDisabledByToggle = !enabled; } }, onSpinDown: function() { var me = this; if (!me.readOnly) { me.setSpinValue(Ext.Number.constrain(me.getValue() - me.step, me.minValue, me.maxValue)); } }, setSpinValue: function(value) { var me = this; if (me.enforceMaxLength) { if (me.fixPrecision(value).toString().length > me.maxLength) { return; } } me.setValue(value); } }); Ext.define('Ext.toolbar.Paging', { extend: 'Ext.toolbar.Toolbar', xtype: 'pagingtoolbar', alternateClassName: 'Ext.PagingToolbar', requires: [ 'Ext.toolbar.TextItem', 'Ext.form.field.Number' ], mixins: [ 'Ext.util.StoreHolder' ], displayInfo: false, prependButtons: false, 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', inputItemWidth: 30, emptyPageData: { total: 0, currentPage: 0, pageCount: 0, toRecord: 0, fromRecord: 0 }, defaultBindProperty: 'store', getPagingItems: function() { var me = this, inputListeners = { scope: me, blur: me.onPagingBlur }; inputListeners[Ext.supports.SpecialKeyDownRepeat ? 'keydown' : 'keypress'] = me.onPagingKeyDown; 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, keyNavEnabled: false, selectOnFocus: true, submitValue: false, isFormField: false, width: me.inputItemWidth, margin: '-1 2 3 2', listeners: inputListeners }, { 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', disabled: me.store.isLoading(), handler: me.doRefresh, scope: me } ]; }, initComponent: function() { var me = this, userItems = me.items || me.buttons || [], pagingItems; me.bindStore(me.store || 'ext-empty-store', true); pagingItems = me.getPagingItems(); if (me.prependButtons) { me.items = userItems.concat(pagingItems); } else { me.items = pagingItems.concat(userItems); } delete me.buttons; if (me.displayInfo) { me.items.push('->'); me.items.push({ xtype: 'tbtext', itemId: 'displayItem' }); } me.callParent(); }, beforeRender: function() { this.callParent(arguments); this.updateBarInfo(); }, updateBarInfo: function() { var me = this; if (!me.store.isLoading()) { me.calledInternal = true; me.onLoad(); me.calledInternal = false; } }, 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); } }, onLoad: function() { var me = this, pageData, currPage, pageCount, afterText, count, isEmpty, item; count = me.store.getCount(); isEmpty = count === 0; if (!isEmpty) { pageData = me.getPageData(); currPage = pageData.currentPage; pageCount = pageData.pageCount; if (currPage > pageCount) { if (pageCount > 0) { me.store.loadPage(pageCount); } else { me.getInputItem().reset(); } return; } afterText = Ext.String.format(me.afterPageText, isNaN(pageCount) ? 1 : pageCount); } else { currPage = 0; pageCount = 0; afterText = Ext.String.format(me.afterPageText, 0); } Ext.suspendLayouts(); item = me.child('#afterTextItem'); if (item) { item.setText(afterText); } item = me.getInputItem(); if (item) { item.setDisabled(isEmpty).setValue(currPage); } me.setChildDisabled('#first', currPage === 1 || isEmpty); me.setChildDisabled('#prev', currPage === 1 || isEmpty); me.setChildDisabled('#next', currPage === pageCount || isEmpty); me.setChildDisabled('#last', currPage === pageCount || isEmpty); me.setChildDisabled('#refresh', false); me.updateInfo(); Ext.resumeLayouts(true); if (!me.calledInternal) { me.fireEvent('change', me, pageData || me.emptyPageData); } }, setChildDisabled: function(selector, disabled) { var item = this.child(selector); if (item) { item.setDisabled(disabled); } }, getPageData: function() { var store = this.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) }; }, onLoadError: function() { this.setChildDisabled('#refresh', false); }, getInputItem: function() { return this.child('#inputItem'); }, readPageFromInput: function(pageData) { var inputItem = this.getInputItem(), pageNum = false, v; if (inputItem) { v = inputItem.getValue(); pageNum = parseInt(v, 10); if (!v || isNaN(pageNum)) { inputItem.setValue(pageData.currentPage); return false; } } return pageNum; }, onPagingBlur: function(e) { var inputItem = this.getInputItem(), curPage; if (inputItem) { curPage = this.getPageData().currentPage; inputItem.setValue(curPage); } }, onPagingKeyDown: function(field, e) { this.processKeyEvent(field, e); }, processKeyEvent: function(field, e) { var me = this, key = e.getKey(), pageData = me.getPageData(), increment = e.shiftKey ? 10 : 1, pageNum; if (key === e.RETURN) { e.stopEvent(); pageNum = me.readPageFromInput(pageData); if (pageNum !== false) { pageNum = Math.min(Math.max(1, pageNum), pageData.pageCount); if (pageNum !== pageData.currentPage && me.fireEvent('beforechange', me, pageNum) !== false) { me.store.loadPage(pageNum); } } } else if (key === e.HOME || key === e.END) { e.stopEvent(); pageNum = key === e.HOME ? 1 : pageData.pageCount; field.setValue(pageNum); } else if (key === e.UP || key === e.PAGE_UP || key === e.DOWN || key === e.PAGE_DOWN) { e.stopEvent(); pageNum = me.readPageFromInput(pageData); if (pageNum) { if (key === e.DOWN || key === e.PAGE_DOWN) { increment *= -1; } pageNum += increment; if (pageNum >= 1 && pageNum <= pageData.pageCount) { field.setValue(pageNum); } } } }, beforeLoad: function() { this.setChildDisabled('#refresh', true); }, moveFirst: function() { if (this.fireEvent('beforechange', this, 1) !== false) { this.store.loadPage(1); return true; } return false; }, movePrevious: function() { var me = this, store = me.store, prev = store.currentPage - 1; if (prev > 0) { if (me.fireEvent('beforechange', me, prev) !== false) { store.previousPage(); return true; } } return false; }, moveNext: function() { var me = this, store = me.store, total = me.getPageData().pageCount, next = store.currentPage + 1; if (next <= total) { if (me.fireEvent('beforechange', me, next) !== false) { store.nextPage(); return true; } } return false; }, moveLast: function() { var me = this, last = me.getPageData().pageCount; if (me.fireEvent('beforechange', me, last) !== false) { me.store.loadPage(last); return true; } return false; }, doRefresh: function() { var me = this, store = me.store, current = store.currentPage; if (me.fireEvent('beforechange', me, current) !== false) { store.loadPage(current); return true; } return false; }, getStoreListeners: function() { return { beforeload: this.beforeLoad, load: this.onLoad, exception: this.onLoadError }; }, onBindStore: function() { if (this.rendered) { this.updateBarInfo(); } }, onDestroy: function() { this.bindStore(null); this.callParent(); } }); Ext.define('Ext.view.BoundList', { extend: 'Ext.view.View', alias: 'widget.boundlist', alternateClassName: 'Ext.BoundList', requires: [ 'Ext.view.BoundListKeyNav', 'Ext.layout.component.BoundList', 'Ext.toolbar.Paging' ], mixins: [ 'Ext.mixin.Queryable' ], pageSize: 0, baseCls: Ext.baseCSSPrefix + 'boundlist', itemCls: Ext.baseCSSPrefix + 'boundlist-item', listItemCls: '', shadow: false, trackOver: true, preserveScrollOnRefresh: true, enableInitialSelection: false, refreshSelmodelOnRefresh: true, componentLayout: 'boundlist', navigationModel: 'boundlist', scrollable: true, childEls: [ 'listWrap', 'listEl' ], renderTpl: [ '', '{%', 'var pagingToolbar=values.$comp.pagingToolbar;', 'if (pagingToolbar) {', 'Ext.DomHelper.generateMarkup(pagingToolbar.getRenderTree(), out);', '}', '%}', { disableFormats: true } ], focusOnToFront: false, initComponent: function() { var me = this, baseCls = me.baseCls, itemCls = me.itemCls; me.selectedItemCls = baseCls + '-selected'; if (me.trackOver) { me.overItemCls = baseCls + '-item-over'; } me.itemSelector = "." + itemCls; me.scrollerSelector = 'ul.' + Ext.baseCSSPrefix + 'list-plain'; if (me.floating) { me.addCls(baseCls + '-floating'); } if (!me.tpl) { me.tpl = new Ext.XTemplate('', '
  • ' + me.getInnerTpl(me.displayField) + '
  • ', '
    '); } else if (!me.tpl.isTemplate) { me.tpl = new Ext.XTemplate(me.tpl); } if (me.pageSize) { me.pagingToolbar = me.createPagingToolbar(); } me.callParent(); }, getRefOwner: function() { return this.pickerField || this.callParent(); }, getRefItems: function() { var result = this.callParent(), toolbar = this.pagingToolbar; if (toolbar) { result.push(toolbar); } return result; }, createPagingToolbar: function() { return Ext.widget('pagingtoolbar', { id: this.id + '-paging-toolbar', pageSize: this.pageSize, store: this.dataSource, border: false, ownerCt: this, ownerLayout: this.getComponentLayout() }); }, getNodeContainer: function() { return this.listEl; }, refresh: function() { var me = this, tpl = me.tpl; tpl.field = me.pickerField; tpl.store = me.store; me.callParent(); tpl.field = tpl.store = null; }, bindStore: function(store, initial) { var toolbar = this.pagingToolbar; this.callParent(arguments); if (toolbar) { toolbar.bindStore(store, initial); } }, getInnerTpl: function(displayField) { return '{' + displayField + '}'; }, onShow: function() { this.callParent(); if (Ext.Element.getActiveElement() !== this.pickerField.inputEl.dom) { this.focus(); } }, onHide: function() { var inputEl = this.pickerField.inputEl.dom; if (Ext.Element.getActiveElement() !== inputEl && (!Ext.EventObject || Ext.EventObject.pointerType !== 'touch')) { inputEl.focus(); } this.callParent(arguments); }, afterComponentLayout: function(width, height, oldWidth, oldHeight) { var picker = this.pickerField; this.callParent(arguments); if (picker && picker.alignPicker) { picker.alignPicker(); } }, onItemClick: function(record) { var me = this, pickerField = me.pickerField, valueField = pickerField.valueField, selected = me.getSelectionModel().getSelection(); if (!pickerField.multiSelect && selected.length) { selected = selected[0]; if (selected && pickerField.isEqual(record.get(valueField), selected.get(valueField)) && pickerField.collapse) { pickerField.collapse(); } } }, onContainerClick: function(e) { if (this.pagingToolbar && this.pagingToolbar.rendered && e.within(this.pagingToolbar.el)) { return false; } }, onDestroy: function() { this.callParent(); Ext.destroyMembers(this, 'pagingToolbar', 'listWrap', 'listEl'); }, privates: { getTargetEl: function() { return this.listEl; }, getOverflowEl: function() { return this.listWrap; }, finishRenderChildren: function() { var toolbar = this.pagingToolbar; this.callParent(arguments); if (toolbar) { toolbar.finishRender(); } } } }); Ext.define('Ext.form.field.ComboBox', { extend: 'Ext.form.field.Picker', requires: [ 'Ext.util.DelayedTask', 'Ext.view.BoundList', 'Ext.data.StoreManager' ], alternateClassName: 'Ext.form.ComboBox', alias: [ 'widget.combobox', 'widget.combo' ], mixins: [ 'Ext.util.StoreHolder' ], config: { filters: null, selection: null, valueNotFoundText: null, displayTpl: false, delimiter: ', ', displayField: 'text' }, publishes: [ 'selection' ], twoWayBindable: [ 'selection' ], triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger', hiddenName: '', collapseOnSelect: false, hiddenDataCls: Ext.baseCSSPrefix + 'hidden-display ' + Ext.baseCSSPrefix + 'form-data-hidden', ariaRole: 'combobox', childEls: { 'hiddenDataEl': true }, filtered: false, afterRender: function() { var me = this; me.callParent(arguments); me.setHiddenValue(me.value); }, multiSelect: false, triggerAction: 'all', allQuery: '', queryParam: 'query', queryMode: 'remote', queryCaching: true, autoLoadOnValue: false, pageSize: 0, anyMatch: false, caseSensitive: false, autoSelect: true, typeAhead: false, typeAheadDelay: 250, selectOnTab: true, forceSelection: false, growToLongestValue: true, clearFilterOnBlur: true, defaultListConfig: { loadingHeight: 70, minWidth: 70, maxHeight: 300, shadow: 'sides' }, transformInPlace: true, clearValueOnEmpty: true, getGrowWidth: function() { var me = this, value = me.inputEl.dom.value, field, store, dataLn, currentLongestLength, i, item, itemLn; if (me.growToLongestValue) { field = me.displayField; store = me.store; dataLn = store.data.length; currentLongestLength = 0; for (i = 0; i < dataLn; i++) { item = store.getAt(i).data[field]; itemLn = item.length; if (itemLn > currentLongestLength) { currentLongestLength = itemLn; value = item; } } } return value; }, initComponent: function() { var me = this, isDefined = Ext.isDefined, store = me.store, transform = me.transform, transformSelect, isLocalMode; 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.'); } if ('pinList' in me) { me.collapseOnSelect = !me.pinList; } if (transform) { transformSelect = Ext.getDom(transform); if (transformSelect) { if (!me.store) { 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; } } } me.bindStore(store || 'ext-empty-store', true, true); isLocalMode = me.queryMode === 'local'; if (!isDefined(me.queryDelay)) { me.queryDelay = isLocalMode ? 10 : 500; } if (!isDefined(me.minChars)) { me.minChars = isLocalMode ? 0 : 4; } me.callParent(); me.doQueryTask = new Ext.util.DelayedTask(me.doRawQuery, me); if (transformSelect) { if (me.transformInPlace) { me.render(transformSelect.parentNode, transformSelect); delete me.renderTo; } Ext.removeNode(transformSelect); } }, getSubTplMarkup: function(fieldData) { var me = this, hiddenDataElMarkup = '', markup = me.callParent(arguments); if (me.hiddenName) { hiddenDataElMarkup = ''; } return hiddenDataElMarkup + markup; }, applyDisplayTpl: function(displayTpl) { var me = this; if (!displayTpl) { displayTpl = new Ext.XTemplate('' + '{[typeof values === "string" ? values : values["' + me.getDisplayField() + '"]]}' + '' + me.getDelimiter() + '' + ''); } else if (!displayTpl.isTemplate) { displayTpl = new Ext.XTemplate(displayTpl); } return displayTpl; }, applyFilters: function(filters, collection) { var me = this; if (filters === null || filters.isFilterCollection) { return filters; } if (filters) { if (!collection) { collection = this.getFilters(); } collection.beginUpdate(); collection.splice(0, collection.length, filters); collection.each(function(filter) { filter.ownerId = me.id; }); collection.endUpdate(); } return collection; }, applyValueNotFoundText: function(v) { var me = this, valueNotFoundRecord = me.valueNotFoundRecord || (me.valueNotFoundRecord = new Ext.data.Model()); valueNotFoundRecord.set(me.displayField, v); if (me.valueField && me.displayField !== me.valueField) { valueNotFoundRecord.set(me.valueField, v); } return v; }, getFilters: function(autoCreate) { var ret = this.filters; if (!ret && autoCreate !== false) { ret = new Ext.util.FilterCollection(); this.setFilters(ret); } return ret; }, updateFilters: function(newFilters, oldFilters) { var me = this; if (oldFilters) { oldFilters.un('endupdate', 'onEndUpdateFilters', me); } if (newFilters) { newFilters.on('endupdate', 'onEndUpdateFilters', me); } me.onEndUpdateFilters(newFilters); }, onEndUpdateFilters: function(filters) { var me = this, was = me.filtered, is = !!filters && (filters.length > 0), old, storeFilters; if (was || is) { me.filtered = is; old = []; storeFilters = me.store.getFilters(); storeFilters.each(function(filter) { if (filter.ownerId === me.id && !filters.contains(filter)) { old.push(filter); } }); storeFilters.splice(0, old, filters.items); } }, completeEdit: function(e) { var me = this, filter = me.queryFilter; this.callParent([ e ]); me.doQueryTask.cancel(); me.assertValue(); if (filter && me.queryMode === 'local' && me.clearFilterOnBlur) { me.getStore().getFilters().remove(filter); } }, onFocus: function(e) { var me = this; me.callParent([ e ]); if (me.triggerAction !== 'all' && me.queryFilter && me.queryMode === 'local' && me.clearFilterOnBlur) { delete me.lastQuery; me.doRawQuery(); } }, assertValue: function() { var me = this, value = me.getRawValue(), displayValue = me.getDisplayValue(), lastRecords = me.lastSelectedRecords, rec; if (me.forceSelection) { if (me.multiSelect) { if (value !== displayValue) { me.setRawValue(displayValue); } } else { rec = me.findRecordByDisplay(value); if (rec) { if (me.getDisplayValue([ me.getRecordDisplayData(rec) ]) !== displayValue) { me.select(rec, true); } } else if (lastRecords) { me.setValue(lastRecords); } else { me.setRawValue(''); } } } me.collapse(); }, onTypeAhead: function() { var me = this, displayField = me.displayField, record = me.store.findRecord(displayField, me.getRawValue()), boundList = me.getPicker(), newValue, len, selStart; 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); } } }, resetToDefault: Ext.emptyFn, beforeReset: function() { var filter = this.queryFilter; this.callParent(); if (filter) { this.getStore().getFilters().remove(filter); } }, onUnbindStore: function() { var me = this, picker = me.picker, filter = me.queryFilter; if (filter && !me.store.isDestroyed) { me.changingFilters = true; me.getStore().removeFilter(filter, true); me.changingFilters = false; } me.pickerSelectionModel.destroy(); if (picker) { picker.bindStore(null); } }, onBindStore: function(store, initial) { var me = this, picker = me.picker, extraKeySpec, valueCollectionConfig; if (store) { if (store.autoCreated) { me.queryMode = 'local'; me.valueField = me.displayField = 'field1'; if (!store.expanded) { me.displayField = 'field2'; } me.setDisplayTpl(null); } if (!Ext.isDefined(me.valueField)) { me.valueField = me.displayField; } extraKeySpec = { byValue: { rootProperty: 'data', unique: false } }; extraKeySpec.byValue.property = me.valueField; store.setExtraKeys(extraKeySpec); if (me.displayField === me.valueField) { store.byText = store.byValue; } else { extraKeySpec.byText = { rootProperty: 'data', unique: false }; extraKeySpec.byText.property = me.displayField; store.setExtraKeys(extraKeySpec); } valueCollectionConfig = { rootProperty: 'data', extraKeys: { byInternalId: { property: 'internalId' }, byValue: { property: me.valueField, rootProperty: 'data' } }, listeners: { beginupdate: me.onValueCollectionBeginUpdate, endupdate: me.onValueCollectionEndUpdate, scope: me } }; me.valueCollection = new Ext.util.Collection(valueCollectionConfig); me.pickerSelectionModel = new Ext.selection.DataViewModel({ mode: me.multiSelect ? 'SIMPLE' : 'SINGLE', deselectOnContainerClick: false, enableInitialSelection: false, pruneRemoved: false, selected: me.valueCollection, store: store, listeners: { scope: me, lastselectedchanged: me.updateBindSelection } }); if (!initial) { me.resetToDefault(); } if (picker) { picker.setSelectionModel(me.pickerSelectionModel); if (picker.getStore() !== store) { picker.bindStore(store); } } } }, bindStore: function(store, preventFilter, initial) { var me = this, filter = me.queryFilter; me.mixins.storeholder.bindStore.call(me, store, initial); store = me.getStore(); if (store && filter && !preventFilter) { store.getFilters().add(filter); } if (!initial && store && !store.isEmptyStore) { me.setValueOnData(); } }, getStoreListeners: function(store) { if (!store.isEmptyStore) { var me = this, result = { datachanged: me.onDataChanged, load: me.onLoad, exception: me.onException, update: me.onStoreUpdate, remove: me.checkValueOnChange }; if (!store.getRemoteFilter()) { result.filterchange = me.checkValueOnChange; } return result; } }, onDataChanged: function() { if (this.grow && this.growToLongestValue) { this.autoSize(); } }, checkValueOnChange: function() { var me = this, store = me.getStore(); if (!me.destroying && store.isLoaded()) { if (me.multiSelect) {} else { if (me.forceSelection && !me.changingFilters && !me.findRecordByValue(me.value)) { me.setValue(null); } } } }, onStoreUpdate: function(store, record) { this.updateValue(); }, onException: function() { this.collapse(); }, onLoad: function(store, records, success) { var me = this, needsValueUpdating = !me.valueCollection.byValue.get(me.value); if (success && needsValueUpdating && !(store.lastOptions && 'rawQuery' in store.lastOptions)) { me.setValueOnData(); } me.checkValueOnChange(); }, setValueOnData: function() { var me = this; me.setValue(me.value); if (me.isExpanded && me.getStore().getCount()) { me.doAutoSelect(); } }, doRawQuery: function() { var me = this, rawValue = me.inputEl.dom.value; if (me.multiSelect) { rawValue = rawValue.split(me.delimiter).pop(); } me.doQuery(rawValue, false, true); }, doQuery: function(queryString, forceAll, rawQuery) { var me = this, queryPlan = me.beforeQuery({ query: queryString || '', rawQuery: rawQuery, forceAll: forceAll, combo: me, cancel: false }); if (queryPlan !== false && !queryPlan.cancel) { if (me.queryCaching && queryPlan.query === me.lastQuery) { me.expand(); } else { me.lastQuery = queryPlan.query; if (me.queryMode === 'local') { me.doLocalQuery(queryPlan); } else { me.doRemoteQuery(queryPlan); } } } return true; }, beforeQuery: function(queryPlan) { var me = this; if (me.fireEvent('beforequery', queryPlan) === false) { queryPlan.cancel = true; } else if (!queryPlan.cancel) { if (queryPlan.query.length < me.minChars && !queryPlan.forceAll) { queryPlan.cancel = true; } } return queryPlan; }, doLocalQuery: function(queryPlan) { var me = this, queryString = queryPlan.query, store = me.getStore(), filter = me.queryFilter; me.queryFilter = null; me.changingFilters = true; if (filter) { store.removeFilter(filter, true); } if (queryString) { filter = me.queryFilter = new Ext.util.Filter({ id: me.id + '-filter', anyMatch: me.anyMatch, caseSensitive: me.caseSensitive, root: 'data', property: me.displayField, value: me.enableRegEx ? new RegExp(queryString) : queryString }); store.addFilter(filter, true); } me.changingFilters = false; if (me.store.getCount() || me.getPicker().emptyText) { me.getPicker().refresh(); me.expand(); } else { me.collapse(); } me.afterQuery(queryPlan); }, doRemoteQuery: function(queryPlan) { var me = this, loadCallback = function() { if (!me.isDestroyed) { me.afterQuery(queryPlan); } }; me.expand(); if (me.pageSize) { me.loadPage(1, { rawQuery: queryPlan.rawQuery, callback: loadCallback }); } else { me.store.load({ params: me.getParams(queryPlan.query), rawQuery: queryPlan.rawQuery, callback: loadCallback }); } }, afterQuery: function(queryPlan) { var me = this; if (me.store.getCount()) { if (me.typeAhead) { me.doTypeAhead(); } if (queryPlan.rawQuery) { if (me.picker && !me.picker.getSelectionModel().hasSelection()) { me.doAutoSelect(); } } else { me.doAutoSelect(); } } me.checkChange(); }, loadPage: function(pageNum, options) { this.store.loadPage(pageNum, Ext.apply({ params: this.getParams(this.lastQuery) }, options)); }, onPageChange: function(toolbar, newPage) { this.loadPage(newPage); return false; }, getParams: function(queryString) { var params = {}, param = this.queryParam; if (param) { params[param] = queryString; } return params; }, doAutoSelect: function() { var me = this, picker = me.picker; if (picker && me.autoSelect && me.store.getCount() > 0) { picker.getNavigationModel().setPosition(me.picker.getSelectionModel().lastSelected || 0); } }, doTypeAhead: function() { var me = this, Event = Ext.event.Event; if (!me.typeAheadTask) { me.typeAheadTask = new Ext.util.DelayedTask(me.onTypeAhead, me); } if (me.lastKey !== Event.BACKSPACE && me.lastKey !== Event.DELETE) { me.typeAheadTask.delay(me.typeAheadDelay); } }, onTriggerClick: function() { var me = this; if (!me.readOnly && !me.disabled) { if (me.isExpanded) { me.collapse(); } else { if (me.triggerAction === 'all') { me.doQuery(me.allQuery, true); } else if (me.triggerAction === 'last') { me.doQuery(me.lastQuery, true); } else { me.doQuery(me.getRawValue(), false, true); } } } }, onFieldMutation: function(e) { var me = this, key = e.getKey(), isDelete = key === e.BACKSPACE || key === e.DELETE, rawValue = me.inputEl.dom.value, len = rawValue.length; if (!me.readOnly && (rawValue !== me.lastMutatedValue || isDelete) && key !== e.TAB) { me.lastMutatedValue = rawValue; me.lastKey = key; if (len && (e.type !== 'keyup' || (!e.isSpecialKey() || isDelete))) { me.doQueryTask.delay(me.queryDelay); } else { if (!len && (!key || isDelete)) { if (!me.multiSelect) { me.value = null; me.displayTplData = undefined; } if (me.clearValueOnEmpty) { me.valueCollection.removeAll(); } me.collapse(); if (me.queryFilter) { me.changingFilters = true; me.store.removeFilter(me.queryFilter, true); me.changingFilters = false; } } me.callParent([ e ]); } } }, onDestroy: function() { var me = this; me.doQueryTask.cancel(); if (me.typeAheadTask) { me.typeAheadTask.cancel(); me.typeAheadTask = null; } me.bindStore(null); me.valueCollection = Ext.destroy(me.valueCollection); me.callParent(); }, onAdded: function() { var me = this; me.callParent(arguments); if (me.picker) { me.picker.ownerCt = me.up('[floating]'); me.picker.registerWithOwnerCt(); } }, createPicker: function() { var me = this, picker, pickerCfg = Ext.apply({ xtype: 'boundlist', pickerField: me, selectionModel: me.pickerSelectionModel, floating: true, hidden: true, store: me.getPickerStore(), displayField: me.displayField, preserveScrollOnRefresh: true, pageSize: me.pageSize, tpl: me.tpl }, me.listConfig, me.defaultListConfig); picker = me.picker = Ext.widget(pickerCfg); if (me.pageSize) { picker.pagingToolbar.on('beforechange', me.onPageChange, me); } if (!picker.initialConfig.maxHeight) { picker.on({ beforeshow: me.onBeforePickerShow, scope: me }); } picker.getSelectionModel().on({ beforeselect: me.onBeforeSelect, beforedeselect: me.onBeforeDeselect, scope: me }); picker.getNavigationModel().navigateOnSpace = false; return picker; }, getPickerStore: function() { return this.store; }, onBeforePickerShow: function(picker) { var me = this, heightAbove = me.getPosition()[1] - Ext.getBody().getScroll().top, heightBelow = Ext.Element.getViewportHeight() - heightAbove - me.getHeight(); picker.maxHeight = Math.max(heightAbove, heightBelow) - 5; }, onBeforeSelect: function(list, record, recordIndex) { return this.fireEvent('beforeselect', this, record, recordIndex); }, onBeforeDeselect: function(list, record, recordIndex) { return this.fireEvent('beforedeselect', this, record, recordIndex); }, getSelection: function() { var selModel = this.getPicker().getSelectionModel(), selection = selModel.getSelection(); return selection.length ? selModel.getLastSelected() : null; }, updateSelection: function(selection) { var me = this, sm; if (!me.ignoreNextSelection) { me.ignoreNextSelection = true; sm = me.getPicker().getSelectionModel(); if (selection) { sm.select(selection); me.hasHadSelection = true; } else { sm.deselectAll(); } me.ignoreNextSelection = false; } }, updateBindSelection: function(selModel, selection) { var me = this, selected = null; if (!me.ignoreNextSelection) { me.ignoreNextSelection = true; if (selection.length) { selected = selModel.getLastSelected(); me.hasHadSelection = true; } if (me.hasHadSelection) { me.setSelection(selected); } me.ignoreNextSelection = false; } }, onValueCollectionBeginUpdate: Ext.emptyFn, onValueCollectionEndUpdate: function() { var me = this, store = me.store, selectedRecords = me.valueCollection.getRange(), selectedRecord = selectedRecords[0], selectionCount = selectedRecords.length; me.updateBindSelection(me.pickerSelectionModel, selectedRecords); if (me.isSelectionUpdating()) { return; } Ext.suspendLayouts(); me.lastSelection = selectedRecords; if (selectionCount) { me.lastSelectedRecords = selectedRecords; } me.updateValue(); if (selectionCount && ((!me.multiSelect && store.contains(selectedRecord)) || me.collapseOnSelect || !store.getCount())) { me.updatingValue = true; me.collapse(); me.updatingValue = false; } Ext.resumeLayouts(true); if (selectionCount && !me.suspendCheckChange) { if (!me.multiSelect) { selectedRecords = selectedRecord; } me.fireEvent('select', me, selectedRecords); } }, isSelectionUpdating: function() { var selModel = this.pickerSelectionModel; return selModel.deselectingDuringSelect || selModel.refreshing; }, onExpand: function() { var keyNav = this.getPicker().getNavigationModel(); if (keyNav) { keyNav.enable(); } this.doAutoSelect(); }, onCollapse: function() { var keyNav = this.getPicker().getNavigationModel(); if (keyNav) { keyNav.disable(); } if (this.updatingValue) { this.doQueryTask.cancel(); } }, select: function(r, assert) { var me = this, picker = me.picker, fireSelect; if (r && r.isModel && assert === true && picker) { fireSelect = !picker.getSelectionModel().isSelected(r); } if (!fireSelect) { me.suspendEvent('select'); } me.setValue(r); me.resumeEvent('select'); }, findRecord: function(field, value) { var ds = this.store, idx = ds.findExact(field, value); return idx !== -1 ? ds.getAt(idx) : false; }, getSelectedRecord: function() { return this.findRecordByValue(this.value) || null; }, findRecordByValue: function(value) { var result = this.store.byValue.get(value), ret = false; if (result) { ret = result[0] || result; } return ret; }, findRecordByDisplay: function(value) { var result = this.store.byText.get(value), ret = false; if (result) { ret = result[0] || result; } return ret; }, addValue: function(value) { if (value != null) { return this.doSetValue(value, true); } }, setValue: function(value) { var me = this; if (value != null) { return me.doSetValue(value); } else { me.suspendEvent('select'); me.valueCollection.beginUpdate(); me.pickerSelectionModel.deselectAll(); me.valueCollection.endUpdate(); me.lastSelectedRecords = null; me.resumeEvent('select'); } }, setRawValue: function(rawValue) { this.callParent([ rawValue ]); this.lastMutatedValue = rawValue; }, doSetValue: function(value, add) { var me = this, store = me.getStore(), Model = store.getModel(), matchedRecords = [], valueArray = [], autoLoadOnValue = me.autoLoadOnValue, isLoaded = store.getCount() > 0 || store.isLoaded(), pendingLoad = store.hasPendingLoad(), unloaded = autoLoadOnValue && !isLoaded && !pendingLoad, forceSelection = me.forceSelection, selModel = me.pickerSelectionModel, displayIsValue = me.displayField === me.valueField, isEmptyStore = store.isEmptyStore, lastSelection = me.lastSelection, i, len, record, dataObj, valueChanged, key; if (add && !me.multiSelect) { Ext.Error.raise('Cannot add values to non multiSelect ComboBox'); } if (pendingLoad || unloaded || !isLoaded || isEmptyStore) { if (!value.isModel) { if (add) { me.value = Ext.Array.from(me.value).concat(value); } else { me.value = value; } me.setHiddenValue(me.value); me.setRawValue(displayIsValue ? value : ''); } if (unloaded && !isEmptyStore) { store.load(); } if (!value.isModel || isEmptyStore) { return me; } } value = add ? Ext.Array.from(me.value).concat(value) : Ext.Array.from(value); for (i = 0 , len = value.length; i < len; i++) { record = value[i]; if (!record || !record.isModel) { record = me.findRecordByValue(key = record); if (!record) { record = me.valueCollection.find(me.valueField, key); } } if (!record) { if (!forceSelection) { if (!record && value[i]) { dataObj = {}; dataObj[me.displayField] = value[i]; if (me.valueField && me.displayField !== me.valueField) { dataObj[me.valueField] = value[i]; } record = new Model(dataObj); } } else if (me.valueNotFoundRecord) { record = me.valueNotFoundRecord; } } if (record) { matchedRecords.push(record); valueArray.push(record.get(me.valueField)); } } if (lastSelection) { len = lastSelection.length; if (len === matchedRecords.length) { for (i = 0; !valueChanged && i < len; i++) { if (Ext.Array.indexOf(me.lastSelection, matchedRecords[i]) === -1) { valueChanged = true; } } } else { valueChanged = true; } } else { valueChanged = matchedRecords.length; } if (valueChanged) { me.suspendEvent('select'); me.valueCollection.beginUpdate(); if (matchedRecords.length) { selModel.select(matchedRecords, false); } else { selModel.deselectAll(); } me.valueCollection.endUpdate(); me.resumeEvent('select'); } else { me.updateValue(); } return me; }, updateValue: function() { var me = this, selectedRecords = me.valueCollection.getRange(), len = selectedRecords.length, valueArray = [], displayTplData = me.displayTplData || (me.displayTplData = []), inputEl = me.inputEl, i, record; displayTplData.length = 0; for (i = 0; i < len; i++) { record = selectedRecords[i]; displayTplData.push(me.getRecordDisplayData(record)); if (record !== me.valueNotFoundRecord) { valueArray.push(record.get(me.valueField)); } } me.setHiddenValue(valueArray); me.value = me.multiSelect ? valueArray : valueArray[0]; if (!Ext.isDefined(me.value)) { me.value = undefined; } me.displayTplData = displayTplData; if (inputEl && me.emptyText && !Ext.isEmpty(me.value)) { inputEl.removeCls(me.emptyCls); } me.setRawValue(me.getDisplayValue()); me.checkChange(); me.applyEmptyText(); }, setHiddenValue: function(values) { var me = this, name = me.hiddenName, i, dom, childNodes, input, valueCount, childrenCount; if (!me.hiddenDataEl || !name) { return; } values = Ext.Array.from(values); dom = me.hiddenDataEl.dom; childNodes = dom.childNodes; input = childNodes[0]; valueCount = values.length; childrenCount = childNodes.length; if (!input && valueCount > 0) { me.hiddenDataEl.setHtml(Ext.DomHelper.markup({ tag: 'input', type: 'hidden', name: name })); childrenCount = 1; input = dom.firstChild; } while (childrenCount > valueCount) { dom.removeChild(childNodes[0]); --childrenCount; } while (childrenCount < valueCount) { dom.appendChild(input.cloneNode(true)); ++childrenCount; } for (i = 0; i < valueCount; i++) { childNodes[i].value = values[i]; } }, getDisplayValue: function(tplData) { tplData = tplData || this.displayTplData; return this.getDisplayTpl().apply(tplData); }, getRecordDisplayData: function(record) { return record.data; }, getValue: function() { var me = this, store = me.getStore(), picker = me.picker, rawValue = me.getRawValue(), value = me.value; if (!store.isEmptyStore && me.getDisplayValue() !== rawValue) { me.displayTplData = undefined; if (picker) { me.valueCollection.suspendEvents(); picker.getSelectionModel().deselectAll(); me.valueCollection.resumeEvents(); me.lastSelection = null; } if (store.isLoaded() && (me.multiSelect || me.forceSelection)) { value = me.value = undefined; } else { value = me.value = rawValue; } } me.value = value == null ? null : value; return me.value; }, getSubmitValue: function() { var value = this.getValue(); if (Ext.isEmpty(value)) { value = ''; } return value; }, 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; } for (i = 0; i < len; i++) { if (v2[i] !== v1[i]) { return false; } } return true; }, clearValue: function() { this.setValue(null); }, onEditorTab: function(e) { var keyNav = this.getPicker().getNavigationModel(); if (this.selectOnTab && keyNav && this.isExpanded) { keyNav.selectHighlighted(e); } } }); 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', isMonthPicker: true, focusable: true, childEls: [ 'bodyEl', 'prevEl', 'nextEl', 'monthEl', 'yearEl' ], renderTpl: [ '
    ', '
    ', '', '
    ', '{.}', '
    ', '
    ', '
    ', '
    ', '
    ', '
    ', '', '
    ', '
    ', '', '
    ', '
    ', '', '
    ', '{.}', '
    ', '
    ', '
    ', '
    ', '', '
    {%', 'var me=values.$comp, okBtn=me.okBtn, cancelBtn=me.cancelBtn;', 'okBtn.ownerLayout = cancelBtn.ownerLayout = me.componentLayout;', 'okBtn.ownerCt = cancelBtn.ownerCt = me;', 'Ext.DomHelper.generateMarkup(okBtn.getRenderTree(), out);', 'Ext.DomHelper.generateMarkup(cancelBtn.getRenderTree(), out);', '%}
    ', '
    ', '
    ' ], okText: 'OK', cancelText: 'Cancel', baseCls: Ext.baseCSSPrefix + 'monthpicker', showButtons: true, measureWidth: 35, measureMaxHeight: 20, smallCls: Ext.baseCSSPrefix + 'monthpicker-small', totalYears: 10, yearOffset: 5, monthOffset: 6, initComponent: function() { var me = this; me.selectedCls = me.baseCls + '-selected'; if (me.small) { me.addCls(me.smallCls); } me.setValue(me.value); me.activeYear = me.getYear(new Date().getFullYear() - 4, -4); if (me.showButtons) { me.okBtn = new Ext.button.Button({ text: me.okText, handler: me.onOkClick, scope: me }); me.cancelBtn = new Ext.button.Button({ text: me.cancelText, handler: me.onCancelClick, scope: me }); } this.callParent(); }, beforeRender: function() { var me = this, i = 0, months = [], shortName = Ext.Date.getShortMonthName, monthLen = me.monthOffset, margin = me.monthMargin, style = ''; if (me.padding && !me.width) { me.cacheWidth(); } me.callParent(); for (; i < monthLen; ++i) { months.push(shortName(i), shortName(i + monthLen)); } if (Ext.isDefined(margin)) { style = 'margin: 0 ' + margin + 'px;'; } Ext.apply(me.renderData, { months: months, years: me.getYears(), showButtons: me.showButtons, monthStyle: style }); }, cacheWidth: function() { var me = this, padding = me.parseBox(me.padding), widthEl = Ext.getBody().createChild({ cls: me.baseCls + ' ' + me.borderBoxCls, style: 'position:absolute;top:-1000px;left:-1000px;', html: ' ' }); me.self.prototype.width = widthEl.getWidth() + padding.left + padding.right; widthEl.destroy(); }, afterRender: function() { var me = this, body = me.bodyEl; me.callParent(); me.mon(body, 'click', me.onBodyClick, me); me.mon(body, 'dblclick', me.onBodyClick, me); me.years = body.select('.' + me.baseCls + '-year a'); me.months = body.select('.' + me.baseCls + '-month a'); me.backRepeater = new Ext.util.ClickRepeater(me.prevEl, { handler: Ext.Function.bind(me.adjustYear, me, [ -me.totalYears ]) }); me.prevEl.addClsOnOver(me.baseCls + '-yearnav-prev-over'); me.nextRepeater = new Ext.util.ClickRepeater(me.nextEl, { handler: Ext.Function.bind(me.adjustYear, me, [ me.totalYears ]) }); me.nextEl.addClsOnOver(me.baseCls + '-yearnav-next-over'); me.updateBody(); if (!Ext.isDefined(me.monthMargin)) { Ext.picker.Month.prototype.monthMargin = me.calculateMonthMargin(); } }, calculateMonthMargin: function() { var me = this, months = me.months, first = months.first(), itemMargin = first.getMargin('l'); while (itemMargin && me.getLargest() > me.measureMaxHeight) { --itemMargin; months.setStyle('margin', '0 ' + itemMargin + 'px'); } return itemMargin; }, getLargest: function(months) { var largest = 0; this.months.each(function(item) { var h = item.getHeight(); if (h > largest) { largest = h; } }); return largest; }, setValue: function(value) { var me = this, active = me.activeYear, year; if (!value) { me.value = [ null, null ]; } else if (Ext.isDate(value)) { me.value = [ value.getMonth(), value.getFullYear() ]; } else { me.value = [ value[0], value[1] ]; } 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; }, getValue: function() { return this.value; }, 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 = []; for (; i < end; ++i) { years.push(i, i + offset); } return years; }, 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, yearItems, y, yLen, el; if (me.rendered) { years.removeCls(cls); months.removeCls(cls); yearItems = years.elements; yLen = yearItems.length; for (y = 0; y < yLen; y++) { el = Ext.fly(yearItems[y]); year = yearNumbers[y]; el.dom.innerHTML = year; if (year === value) { el.addCls(cls); } } if (month !== null) { if (month < monthOffset) { month = month * 2; } else { month = (month - monthOffset) * 2 + 1; } months.item(month).addCls(cls); } } }, getYear: function(defaultValue, offset) { var year = this.value[1]; offset = offset || 0; return year === null ? defaultValue : year + offset; }, onBodyClick: function(e, t) { var me = this, isDouble = e.type === 'dblclick'; 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); } }, adjustYear: function(offset) { if (typeof offset !== 'number') { offset = this.totalYears; } this.activeYear += offset; this.updateBody(); }, onOkClick: function() { this.fireEvent('okclick', this, this.value); }, onCancelClick: function() { this.fireEvent('cancelclick', 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(me, 'backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn'); me.callParent(); }, onDestroy: function() { Ext.destroyMembers(this, 'okBtn', 'cancelBtn'); this.callParent(); }, privates: { finishRenderChildren: function() { var me = this; this.callParent(arguments); if (this.showButtons) { me.okBtn.finishRender(); me.cancelBtn.finishRender(); } } } }); Ext.define('Ext.picker.Date', { extend: 'Ext.Component', requires: [ 'Ext.XTemplate', 'Ext.button.Button', 'Ext.button.Split', 'Ext.util.ClickRepeater', 'Ext.util.KeyNav', 'Ext.fx.Manager', 'Ext.picker.Month' ], alias: 'widget.datepicker', alternateClassName: 'Ext.DatePicker', isDatePicker: true, focusable: true, childEls: [ 'innerEl', 'eventEl', 'prevEl', 'nextEl', 'middleBtnEl', 'footerEl' ], border: true, renderTpl: [ '
    ', '
    ', '
    ', '
    {%this.renderMonthBtn(values, out)%}
    ', '
    ', '
    ', '', '', '', '', '', '', '', '', '{#:this.isEndOfWeek}', '', '', '', '
    ', '', '
    ', '
    ', '
    ', '', '', '', '
    ', { firstInitial: function(value) { return Ext.picker.Date.prototype.getDayInitial(value); }, isEndOfWeek: function(value) { value--; var end = value % 7 === 0 && value !== 0; return end ? '' : ''; }, renderTodayBtn: function(values, out) { Ext.DomHelper.generateMarkup(values.$comp.todayBtn.getRenderTree(), out); }, renderMonthBtn: function(values, out) { Ext.DomHelper.generateMarkup(values.$comp.monthBtn.getRenderTree(), out); } } ], todayText: 'Today', ariaTitle: 'Date Picker: {0}', ariaTitleDateFormat: 'F d', todayTip: '{0} (Spacebar)', minText: 'This date is before the minimum date', maxText: 'This date is after the maximum date', disabledDaysText: 'Disabled', disabledDatesText: 'Disabled', nextText: 'Next Month (Control+Right)', prevText: 'Previous Month (Control+Left)', monthYearText: 'Choose a month (Control+Up/Down to move years)', monthYearFormat: 'F Y', startDay: 0, showToday: true, disableAnim: false, baseCls: Ext.baseCSSPrefix + 'datepicker', longDayFormat: 'F d, Y', initHour: 12, numDays: 42, initComponent: function() { var me = this, clearTime = Ext.Date.clearTime; me.selectedCls = me.baseCls + '-selected'; me.disabledCellCls = me.baseCls + '-disabled'; me.prevCls = me.baseCls + '-prevday'; me.activeCls = me.baseCls + '-active'; me.cellCls = me.baseCls + '-cell'; me.nextCls = me.baseCls + '-prevday'; me.todayCls = me.baseCls + '-today'; if (!me.format) { me.format = Ext.Date.defaultFormat; } if (!me.dayNames) { me.dayNames = Ext.Date.dayNames; } me.dayNames = me.dayNames.slice(me.startDay).concat(me.dayNames.slice(0, me.startDay)); me.callParent(); me.value = me.value ? clearTime(me.value, true) : clearTime(new Date()); me.initDisabledDays(); }, getRefOwner: function() { return this.pickerField || this.callParent(); }, getRefItems: function() { var results = [], monthBtn = this.monthBtn, todayBtn = this.todayBtn; if (monthBtn) { results.push(monthBtn); } if (todayBtn) { results.push(todayBtn); } return results; }, beforeRender: function() { var me = this, days = new Array(me.numDays), today = Ext.Date.format(new Date(), me.format); if (me.padding && !me.width) { me.cacheWidth(); } me.monthBtn = new Ext.button.Split({ ownerCt: me, ownerLayout: me.getComponentLayout(), text: '', tooltip: me.monthYearText, listeners: { click: me.doShowMonthPicker, arrowclick: me.doShowMonthPicker, scope: me } }); if (me.showToday) { me.todayBtn = new Ext.button.Button({ ownerCt: me, ownerLayout: me.getComponentLayout(), text: Ext.String.format(me.todayText, today), tooltip: Ext.String.format(me.todayTip, today), tooltipType: 'title', handler: me.selectToday, scope: me }); } me.callParent(); Ext.applyIf(me, { renderData: {} }); Ext.apply(me.renderData, { dayNames: me.dayNames, showToday: me.showToday, prevText: me.prevText, nextText: me.nextText, days: days }); me.protoEl.unselectable(); }, cacheWidth: function() { var me = this, padding = me.parseBox(me.padding), widthEl = Ext.getBody().createChild({ cls: me.baseCls + ' ' + me.borderBoxCls, style: 'position:absolute;top:-1000px;left:-1000px;' }); me.self.prototype.width = widthEl.getWidth() + padding.left + padding.right; widthEl.destroy(); }, onRender: function(container, position) { var me = this; me.callParent(arguments); me.cells = me.eventEl.select('tbody td'); me.textNodes = me.eventEl.query('tbody td div'); me.eventEl.set({ 'aria-labelledby': me.monthBtn.id }); me.mon(me.eventEl, { scope: me, mousewheel: me.handleMouseWheel, click: { fn: me.handleDateClick, delegate: 'div.' + me.baseCls + '-date' } }); }, initEvents: function() { var me = this, pickerField = me.pickerField, eDate = Ext.Date, day = eDate.DAY; me.callParent(); if (!me.focusable) { me.el.on({ mousedown: me.onMouseDown }); } me.prevRepeater = new Ext.util.ClickRepeater(me.prevEl, { handler: me.showPrevMonth, scope: me, preventDefault: true, stopDefault: true }); me.nextRepeater = new Ext.util.ClickRepeater(me.nextEl, { handler: me.showNextMonth, scope: me, preventDefault: true, stopDefault: true }); me.keyNav = new Ext.util.KeyNav(pickerField ? pickerField.inputEl : me.eventEl, Ext.apply({ scope: me, capture: true, left: function(e) { if (e.ctrlKey) { me.showPrevMonth(); } else { me.update(eDate.add(me.activeDate, day, -1)); } }, right: function(e) { if (e.ctrlKey) { me.showNextMonth(); } else { me.update(eDate.add(me.activeDate, day, 1)); } }, up: function(e) { if (e.ctrlKey) { me.showNextYear(); } else { me.update(eDate.add(me.activeDate, day, -7)); } }, down: function(e) { if (e.ctrlKey) { me.showPrevYear(); } else { me.update(eDate.add(me.activeDate, day, 7)); } }, pageUp: function(e) { if (e.ctrlKey) { me.showPrevYear(); } else { me.showPrevMonth(); } }, pageDown: function(e) { if (e.ctrlKey) { me.showNextYear(); } else { me.showNextMonth(); } }, tab: function(e) { me.handleTabClick(e); return true; }, enter: function(e) { me.handleDateClick(e, me.activeCell.firstChild); }, space: function() { me.setValue(new Date(me.activeCell.firstChild.dateValue)); var startValue = me.startValue, value = me.value, pickerValue; if (pickerField) { pickerValue = pickerField.getValue(); if (pickerValue && startValue && pickerValue.getTime() === value.getTime()) { pickerField.setValue(startValue); } else { pickerField.setValue(value); } } }, home: function(e) { me.update(eDate.getFirstDateOfMonth(me.activeDate)); }, end: function(e) { me.update(eDate.getLastDateOfMonth(me.activeDate)); } }, me.keyNavConfig)); if (me.disabled) { me.syncDisabled(true); } me.update(me.value); }, onMouseDown: function(e) { e.preventDefault(); }, handleTabClick: function(e) { var me = this, t = me.getSelectedDate(me.activeDate), handler = me.handler; if (!me.disabled && t.dateValue && !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)) { me.setValue(new Date(t.dateValue)); me.fireEvent('select', me, me.value); if (handler) { handler.call(me.scope || me, me, me.value); } me.onSelect(); } }, getSelectedDate: function(date) { var me = this, t = date.getTime(), cells = me.cells, cls = me.selectedCls, cellItems = cells.elements, cLen = cellItems.length, cell, c; cells.removeCls(cls); for (c = 0; c < cLen; c++) { cell = cellItems[c].firstChild; if (cell.dateValue === t) { return cell; } } return null; }, initDisabledDays: function() { var me = this, dd = me.disabledDates, re = '(?:', len, d, dLen, dI; if (!me.disabledDatesRE && dd) { len = dd.length - 1; dLen = dd.length; for (d = 0; d < dLen; d++) { dI = dd[d]; re += Ext.isDate(dI) ? '^' + Ext.String.escapeRegex(Ext.Date.dateFormat(dI, me.format)) + '$' : dI; if (d !== len) { re += '|'; } } me.disabledDatesRE = new RegExp(re + ')'); } }, setDisabledDates: function(dd) { var me = this; if (Ext.isArray(dd)) { me.disabledDates = dd; me.disabledDatesRE = null; } else { me.disabledDatesRE = dd; } me.initDisabledDays(); me.update(me.value, true); return me; }, setDisabledDays: function(dd) { this.disabledDays = dd; return this.update(this.value, true); }, setMinDate: function(dt) { this.minDate = dt; return this.update(this.value, true); }, setMaxDate: function(dt) { this.maxDate = dt; return this.update(this.value, true); }, setValue: function(value) { this.value = Ext.Date.clearTime(value || new Date(), true); return this.update(this.value); }, getValue: function() { return this.value; }, getDayInitial: function(value) { return value.substr(0, 1); }, onEnable: function() { var me = this; me.callParent(); me.syncDisabled(false); me.update(me.activeDate); }, onShow: function() { var me = this; me.callParent(); me.syncDisabled(false); if (me.pickerField) { me.startValue = me.pickerField.getValue(); } }, onHide: function() { this.callParent(); this.syncDisabled(true); }, onDisable: function() { this.callParent(); this.syncDisabled(true); }, getActive: function() { return this.activeDate || this.value; }, runAnimation: function(isHide) { var picker = this.monthPicker, options = { duration: 200, callback: function() { picker.setVisible(!isHide); } }; if (isHide) { picker.el.slideOut('t', options); } else { picker.el.slideIn('t', options); } }, hideMonthPicker: function(animate) { var me = this, picker = me.monthPicker; if (picker && picker.isVisible()) { if (me.shouldAnimate(animate)) { me.runAnimation(true); } else { picker.hide(); } } return me; }, doShowMonthPicker: function() { this.showMonthPicker(); }, doHideMonthPicker: function() { this.hideMonthPicker(); }, showMonthPicker: function(animate) { var me = this, el = me.el, picker; if (me.rendered && !me.disabled) { picker = me.createMonthPicker(); if (!picker.isVisible()) { picker.setValue(me.getActive()); picker.setSize(el.getSize()); picker.floatParent = null; picker.setPosition(-el.getBorderWidth('l'), -el.getBorderWidth('t')); if (me.shouldAnimate(animate)) { me.runAnimation(false); } else { picker.show(); } } } return me; }, shouldAnimate: function(animate) { return Ext.isDefined(animate) ? animate : !this.disableAnim; }, createMonthPicker: function() { var me = this, picker = me.monthPicker; if (!picker) { me.monthPicker = picker = new Ext.picker.Month({ renderTo: me.el, ownerCmp: me, floating: true, padding: me.padding, shadow: false, small: me.showToday === false, listeners: { scope: me, cancelclick: me.onCancelClick, okclick: me.onOkClick, yeardblclick: me.onOkClick, monthdblclick: me.onOkClick } }); if (!me.disableAnim) { picker.el.setStyle('display', 'none'); } picker.hide(); me.on('beforehide', me.doHideMonthPicker, me); } return picker; }, 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 = Ext.Date.getLastDateOfMonth(new Date(year, month, 1)); } me.setValue(date); me.hideMonthPicker(); }, onCancelClick: function() { this.selectedUpdate(this.activeDate); this.hideMonthPicker(); }, showPrevMonth: function(e) { return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.MONTH, -1)); }, showNextMonth: function(e) { return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.MONTH, 1)); }, showPrevYear: function() { return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.YEAR, -1)); }, showNextYear: function() { return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.YEAR, 1)); }, handleMouseWheel: function(e) { e.stopEvent(); if (!this.disabled) { var delta = e.getWheelDelta(); if (delta > 0) { this.showPrevMonth(); } else if (delta < 0) { this.showNextMonth(); } } }, handleDateClick: function(e, t) { var me = this, handler = me.handler; e.stopEvent(); if (!me.disabled && t.dateValue && !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)) { me.setValue(new Date(t.dateValue)); me.fireEvent('select', me, me.value); if (handler) { handler.call(me.scope || me, me, me.value); } me.onSelect(); } }, onSelect: function() { if (this.hideOnSelect) { this.hide(); } }, selectToday: function() { var me = this, btn = me.todayBtn, handler = me.handler; 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; }, selectedUpdate: function(date) { var me = this, t = date.getTime(), cells = me.cells, cls = me.selectedCls, c, cLen = cells.getCount(), cell; cell = me.activeCell; if (cell) { Ext.fly(cell).removeCls(cls); cell.setAttribute('aria-selected', false); } for (c = 0; c < cLen; c++) { cell = cells.item(c); if (me.textNodes[c].dateValue === t) { me.activeCell = cell.dom; me.eventEl.dom.setAttribute('aria-activedescendant', cell.dom.id); cell.dom.setAttribute('aria-selected', true); cell.addCls(cls); me.fireEvent('highlightitem', me, cell); break; } } }, fullUpdate: function(date) { var me = this, cells = me.cells.elements, textNodes = me.textNodes, disabledCls = me.disabledCellCls, eDate = Ext.Date, i = 0, extraDays = 0, newDate = +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), ariaTitleDateFormat = me.ariaTitleDateFormat, prevStart, current, disableToday, tempDate, setCellClass, html, cls, formatValue, value; if (startingPos < 0) { startingPos += 7; } days += startingPos; prevStart = eDate.getDaysInMonth(previousMonth) - startingPos; current = new Date(previousMonth.getFullYear(), previousMonth.getMonth(), prevStart, me.initHour); 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); } } setCellClass = function(cellIndex, cls) { var cell = cells[cellIndex]; value = +eDate.clearTime(current, true); cell.setAttribute('aria-label', eDate.format(current, ariaTitleDateFormat)); cell.firstChild.dateValue = value; if (value === today) { cls += ' ' + me.todayCls; cell.firstChild.title = me.todayText; me.todayElSpan = Ext.DomHelper.append(cell.firstChild, { tag: 'span', cls: Ext.baseCSSPrefix + 'hidden-clip', html: me.todayText }, true); } if (value === newDate) { me.activeCell = cell; me.eventEl.dom.setAttribute('aria-activedescendant', cell.id); cell.setAttribute('aria-selected', true); cls += ' ' + me.selectedCls; me.fireEvent('highlightitem', me, cell); } else { cell.setAttribute('aria-selected', false); } if (value < min) { cls += ' ' + disabledCls; cell.setAttribute('aria-label', me.minText); } else if (value > max) { cls += ' ' + disabledCls; cell.setAttribute('aria-label', me.maxText); } else if (ddays && ddays.indexOf(current.getDay()) !== -1) { cell.setAttribute('aria-label', ddaysText); cls += ' ' + disabledCls; } else if (ddMatch && format) { formatValue = eDate.dateFormat(current, format); if (ddMatch.test(formatValue)) { cell.setAttribute('aria-label', ddText.replace('%0', formatValue)); cls += ' ' + disabledCls; } } cell.className = cls + ' ' + me.cellCls; }; 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; current.setDate(current.getDate() + 1); setCellClass(i, cls); } me.monthBtn.setText(Ext.Date.format(date, me.monthYearFormat)); }, update: function(date, forceRefresh) { var me = this, active = me.activeDate; 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); } } return me; }, beforeDestroy: function() { var me = this; if (me.rendered) { Ext.destroy(me.keyNav, me.monthPicker, me.monthBtn, me.nextRepeater, me.prevRepeater, me.todayBtn, me.todayElSpan); delete me.textNodes; delete me.cells.elements; } me.callParent(); }, privates: { finishRenderChildren: function() { var me = this; me.callParent(); me.monthBtn.finishRender(); if (me.showToday) { me.todayBtn.finishRender(); } }, getFocusEl: function() { return this.eventEl; }, syncDisabled: function(disabled) { var me = this, keyNav = me.keyNav; if (keyNav) { keyNav.setDisabled(disabled); me.prevRepeater.setDisabled(disabled); me.nextRepeater.setDisabled(disabled); if (me.todayBtn) { me.todayBtn.setDisabled(disabled); } } } } }); 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, useStrict: undefined, initTime: '12', initTimeFormat: 'H', matchFieldWidth: false, startDay: 0, valuePublishEvent: [ 'select', 'blur' ], initComponent: function() { var me = this, isString = Ext.isString, min, max; 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(); }, 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 = "(?:", d, dLen = dd.length, date; for (d = 0; d < dLen; d++) { date = dd[d]; re += Ext.isDate(date) ? '^' + Ext.String.escapeRegex(date.dateFormat(this.format)) + '$' : date; if (d !== len) { re += '|'; } } this.disabledDatesRE = new RegExp(re + ')'); } }, setDisabledDates: function(disabledDates) { var me = this, picker = me.picker; me.disabledDates = disabledDates; me.initDisabledDays(); if (picker) { picker.setDisabledDates(me.disabledDatesRE); } }, setDisabledDays: function(disabledDays) { var picker = this.picker; this.disabledDays = disabledDays; if (picker) { picker.setDisabledDays(disabledDays); } }, setMinValue: function(value) { var me = this, picker = me.picker, minValue = (Ext.isString(value) ? me.parseDate(value) : value); me.minValue = minValue; if (picker) { picker.minText = Ext.String.format(me.minText, me.formatDate(me.minValue)); picker.setMinDate(minValue); } }, setMaxValue: function(value) { var me = this, picker = me.picker, maxValue = (Ext.isString(value) ? me.parseDate(value) : value); me.maxValue = maxValue; if (picker) { picker.maxText = Ext.String.format(me.maxText, me.formatDate(me.maxValue)); picker.setMaxDate(maxValue); } }, getErrors: function(value) { value = arguments.length > 0 ? value : this.formatDate(this.processRawValue(this.getRawValue())); var me = this, format = Ext.String.format, clearTime = Ext.Date.clearTime, errors = me.callParent([ value ]), disabledDays = me.disabledDays, disabledDatesRE = me.disabledDatesRE, minValue = me.minValue, maxValue = me.maxValue, len = disabledDays ? disabledDays.length : 0, i = 0, svalue, fvalue, day, time; if (value === null || value.length < 1) { return errors; } svalue = value; value = me.parseDate(value); if (!value) { errors.push(format(me.invalidText, svalue, Ext.Date.unescapeFormat(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; } } } fvalue = me.formatDate(value); if (disabledDatesRE && disabledDatesRE.test(fvalue)) { errors.push(format(me.disabledDatesText, fvalue)); } return errors; }, rawToValue: function(rawValue) { return this.parseDate(rawValue) || rawValue || null; }, valueToRaw: function(value) { return this.formatDate(this.parseDate(value)); }, safeParse: function(value, format) { var me = this, utilDate = Ext.Date, result = null, strict = me.useStrict, parsedDate; if (utilDate.formatContainsHourInfo(format)) { result = utilDate.parse(value, format, strict); } else { parsedDate = utilDate.parse(value + ' ' + me.initTime, format + ' ' + me.initTimeFormat, strict); if (parsedDate) { result = utilDate.clearTime(parsedDate); } } return result; }, getSubmitValue: function() { var format = this.submitFormat || this.format, value = this.getValue(); return value ? Ext.Date.format(value, format) : ''; }, parseDate: function(value) { if (!value || Ext.isDate(value)) { return value; } 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; }, formatDate: function(date) { return Ext.isDate(date) ? Ext.Date.dateFormat(date, this.format) : date; }, createPicker: function() { var me = this, format = Ext.String.format; return new Ext.picker.Date({ pickerField: me, floating: true, focusable: false, hidden: 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(); } } }); }, onSelect: function(m, d) { var me = this; me.setValue(d); me.fireEvent('select', me, d); me.collapse(); }, onExpand: function() { var value = this.getValue(); this.picker.setValue(Ext.isDate(value) ? value : new Date()); }, onBlur: function(e) { var me = this, v = me.rawToValue(me.getRawValue()); if (Ext.isDate(v)) { me.setValue(v); } me.callParent([ e ]); } }); Ext.define('Ext.form.field.FileButton', { extend: 'Ext.button.Button', alias: 'widget.filebutton', childEls: [ 'fileInputEl' ], inputCls: Ext.baseCSSPrefix + 'form-file-input', cls: Ext.baseCSSPrefix + 'form-file-btn', preventDefault: false, tabIndex: null, autoEl: { tag: 'div', unselectable: 'on' }, afterTpl: [ 'tabindex="{tabIndex}"', '>' ], getAfterMarkup: function(values) { return this.getTpl('afterTpl').apply(values); }, getTemplateArgs: function() { var args = this.callParent(); args.inputCls = this.inputCls; args.inputName = this.inputName; args.tabIndex = this.ownerCt.tabIndex; return args; }, afterRender: function() { var me = this; me.callParent(arguments); me.fileInputEl.on({ scope: me, change: me.fireChange, focus: me.onFileFocus, blur: me.onFileBlur }); }, fireChange: function(e) { this.fireEvent('change', this, e, this.fileInputEl.dom.value); }, createFileInput: function(isTemporary) { var me = this, fileInputEl = me.fileInputEl = me.el.createChild({ name: me.inputName, id: !isTemporary ? me.id + '-fileInputEl' : undefined, cls: me.inputCls, tag: 'input', type: 'file', size: 1, role: 'button' }); fileInputEl.dom.setAttribute(Ext.Component.componentIdAttribute, me.id); fileInputEl.on({ scope: me, change: me.fireChange, focus: me.onFileFocus, blur: me.onFileBlur }); }, onFileFocus: function(e) { var ownerCt = this.ownerCt; if (!this.hasFocus) { this.onFocus(e); } if (ownerCt && !ownerCt.hasFocus) { ownerCt.onFocus(e); } }, onFileBlur: function(e) { var ownerCt = this.ownerCt; if (this.hasFocus) { this.onBlur(e); } if (ownerCt && ownerCt.hasFocus) { ownerCt.onBlur(e); } }, reset: function(remove) { var me = this; if (remove) { me.fileInputEl.destroy(); } me.createFileInput(!remove); }, restoreInput: function(el) { var me = this; me.fileInputEl.destroy(); el = Ext.get(el); me.el.appendChild(el); me.fileInputEl = el; }, onDisable: function() { this.callParent(); this.fileInputEl.dom.disabled = true; }, onEnable: function() { this.callParent(); this.fileInputEl.dom.disabled = false; }, privates: { getFocusEl: function() { return this.fileInputEl; }, getFocusClsEl: function() { return this.el; } } }); Ext.define('Ext.form.trigger.Component', { extend: 'Ext.form.trigger.Trigger', alias: 'trigger.component', cls: Ext.baseCSSPrefix + 'form-trigger-cmp', onFieldRender: function() { var me = this, component = me.component; me.callParent(); if (!component.isComponent && !component.isWidget) { component = Ext.widget(component); } me.component = component; component.render(me.el); }, destroy: function() { var component = this.component; if (component.isComponent || component.isWidget) { component.destroy(); } this.component = null; this.callParent(); } }); 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' ], requires: [ 'Ext.form.field.FileButton', 'Ext.form.trigger.Component' ], needArrowKeys: false, triggers: { filebutton: { type: 'component', hideOnReadOnly: false, preventMouseDown: false } }, buttonText: 'Browse...', buttonOnly: false, buttonMargin: 3, clearOnSubmit: true, extraFieldBodyCls: Ext.baseCSSPrefix + 'form-file-wrap', inputCls: Ext.baseCSSPrefix + 'form-text-file', readOnly: true, editable: false, submitValue: false, triggerNoEditCls: '', childEls: [ 'browseButtonWrap' ], applyTriggers: function(triggers) { var me = this, triggerCfg = (triggers || {}).filebutton; if (triggerCfg) { triggerCfg.component = Ext.apply({ xtype: 'filebutton', ownerCt: me, id: me.id + '-button', ui: me.ui, disabled: me.disabled, text: me.buttonText, style: me.buttonOnly ? '' : me.getButtonMarginProp() + me.buttonMargin + 'px', inputName: me.getName(), listeners: { scope: me, change: me.onFileChange } }, me.buttonConfig); return me.callParent([ triggers ]); } else { Ext.Error.raise(me.$className + ' requires a valid trigger config containing "filebutton" specification'); } }, getSubTplData: function(fieldData) { var data = this.callParent([ fieldData ]); data.tabIdx = -1; return data; }, onRender: function() { var me = this, inputEl, button, buttonEl, trigger; me.callParent(arguments); inputEl = me.inputEl; inputEl.dom.name = ''; inputEl.on('focus', me.focus, me); trigger = me.getTrigger('filebutton'); button = me.button = trigger.component; me.fileInputEl = button.fileInputEl; buttonEl = button.el; if (me.buttonOnly) { me.inputWrap.setDisplayed(false); me.shrinkWrap = 3; } trigger.el.setWidth(buttonEl.getWidth() + buttonEl.getMargin('lr')); if (Ext.isIE) { me.button.getEl().repaint(); } }, getTriggerMarkup: function() { return ''; }, onFileChange: function(button, e, value) { this.duringFileSelect = true; Ext.form.field.File.superclass.setValue.call(this, value); delete this.duringFileSelect; }, didValueChange: function() { return !!this.duringFileSelect; }, setValue: Ext.emptyFn, reset: function() { var me = this, clear = me.clearOnSubmit; if (me.rendered) { me.button.reset(clear); me.fileInputEl = me.button.fileInputEl; if (clear) { me.inputEl.dom.value = ''; Ext.form.field.File.superclass.setValue.call(this, null); } } me.callParent(); }, onShow: function() { this.callParent(); this.button.updateLayout(); }, onDisable: function() { this.callParent(); this.button.disable(); }, onEnable: function() { this.callParent(); this.button.enable(); }, isFileUpload: Ext.returnTrue, extractFileInput: function() { var me = this, fileInput; if (me.rendered) { fileInput = me.button.fileInputEl.dom; me.reset(); } else { fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.className = Ext.baseCSSPrefix + 'hidden-display'; fileInput.name = me.getName(); } return fileInput; }, restoreInput: function(el) { if (this.rendered) { var button = this.button; button.restoreInput(el); this.fileInputEl = button.fileInputEl; } }, onDestroy: function() { this.fileInputEl = this.button = null; this.callParent(); }, getButtonMarginProp: function() { return 'margin-left:'; }, privates: { getFocusEl: function() { return this.button; }, getFocusClsEl: Ext.privateFn } }); Ext.define('Ext.form.field.Hidden', { extend: 'Ext.form.field.Base', alias: [ 'widget.hiddenfield', 'widget.hidden' ], alternateClassName: 'Ext.form.Hidden', focusable: false, inputType: 'hidden', isTextInput: false, hideLabel: true, hidden: true, ariaRole: 'presentation', initComponent: function() { this.formItemCls += '-hidden'; this.callParent(); }, isEqual: function(value1, value2) { return this.isEqualAsString(value1, value2); }, initEvents: Ext.emptyFn, setSize: Ext.emptyFn, setWidth: Ext.emptyFn, setHeight: Ext.emptyFn, setPosition: Ext.emptyFn, setPagePosition: Ext.emptyFn, markInvalid: Ext.emptyFn, clearInvalid: Ext.emptyFn }); Ext.define('Ext.picker.Color', { extend: 'Ext.Component', requires: 'Ext.XTemplate', alias: 'widget.colorpicker', alternateClassName: 'Ext.ColorPalette', focusable: true, componentCls: Ext.baseCSSPrefix + 'color-picker', selectedCls: Ext.baseCSSPrefix + 'color-picker-selected', itemCls: Ext.baseCSSPrefix + 'color-picker-item', value: null, clickEvent: 'click', allowReselect: false, 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' ], colorRe: /(?:^|\s)color-(.{6})(?:\s|$)/, renderTpl: [ '', '', ' ', '', '' ], initComponent: function() { var me = this; me.callParent(arguments); if (me.handler) { me.on('select', me.handler, me.scope, true); } }, initRenderData: function() { var me = this; return Ext.apply(me.callParent(), { itemCls: me.itemCls, colors: me.colors }); }, onRender: function() { var me = this, clickEvent = me.clickEvent; me.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() { var me = this, value; me.callParent(arguments); if (me.value) { value = me.value; me.value = null; me.select(value, true); } }, handleClick: function(event) { var me = this, color; event.stopEvent(); if (!me.disabled) { color = event.currentTarget.className.match(me.colorRe)[1]; me.select(color.toUpperCase()); } }, select: function(color, suppressEvent) { var me = this, selectedCls = me.selectedCls, value = me.value, el, item; color = color.replace('#', ''); if (!me.rendered) { me.value = color; return; } if (color !== value || me.allowReselect) { el = me.el; if (me.value) { item = el.down('a.color-' + value, true); Ext.fly(item).removeCls(selectedCls); } item = el.down('a.color-' + color, true); Ext.fly(item).addCls(selectedCls); me.value = color; if (suppressEvent !== true) { me.fireEvent('select', me, color); } } }, clear: function() { var me = this, value = me.value, el; if (value && me.rendered) { el = me.el.down('a.color-' + value, true); Ext.fly(el).removeCls(me.selectedCls); } me.value = null; }, getValue: function() { return this.value || null; } }); Ext.define('Ext.layout.component.field.HtmlEditor', { extend: 'Ext.layout.component.field.FieldContainer', alias: [ 'layout.htmleditor' ], type: 'htmleditor', naturalHeight: 150, naturalWidth: 300, beginLayout: function(ownerContext) { var owner = this.owner, dom; if (Ext.isGecko) { dom = owner.textareaEl.dom; this.lastValue = dom.value; dom.value = ''; } this.callParent(arguments); ownerContext.toolbarContext = ownerContext.context.getCmp(owner.toolbar); ownerContext.inputCmpContext = ownerContext.context.getCmp(owner.inputCmp); ownerContext.bodyCellContext = ownerContext.getEl('bodyEl'); ownerContext.textAreaContext = ownerContext.getEl('textareaEl'); ownerContext.iframeContext = ownerContext.getEl('iframeEl'); }, beginLayoutCycle: function(ownerContext) { var me = this, widthModel = ownerContext.widthModel, heightModel = ownerContext.heightModel, owner = me.owner, iframeEl = owner.iframeEl, textareaEl = owner.textareaEl, height = (heightModel.natural || heightModel.shrinkWrap) ? me.naturalHeight : ''; me.callParent(arguments); if (widthModel.shrinkWrap) { iframeEl.setStyle('width', ''); textareaEl.setStyle('width', ''); } else if (widthModel.natural) { ownerContext.bodyCellContext.setWidth(me.naturalWidth); } iframeEl.setStyle('height', height); textareaEl.setStyle('height', height); }, finishedLayout: function() { var owner = this.owner; this.callParent(arguments); if (Ext.isGecko) { owner.textareaEl.dom.value = this.lastValue; } } }); Ext.define('Ext.toolbar.Separator', { extend: 'Ext.toolbar.Item', requires: [ 'Ext.toolbar.Toolbar' ], alias: 'widget.tbseparator', alternateClassName: 'Ext.Toolbar.Separator', baseCls: Ext.baseCSSPrefix + 'toolbar-separator', ariaRole: 'separator' }); 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', alias: [ 'box.overflow.menu', 'box.overflow.Menu' ], noItemsMenuText: '', menuCls: Ext.baseCSSPrefix + 'box-menu', constructor: function(config) { var me = this; me.callParent([ config ]); me.menuItems = []; }, beginLayout: function(ownerContext) { this.callParent([ ownerContext ]); this.clearOverflow(ownerContext); }, beginLayoutCycle: function(ownerContext, firstCycle) { this.callParent([ ownerContext, firstCycle ]); if (!firstCycle) { this.clearOverflow(ownerContext); this.layout.cacheChildItems(ownerContext); } }, onRemove: function(comp) { Ext.Array.remove(this.menuItems, comp); }, clearItem: function(comp) { var menu = comp.menu; if (comp.isButton && menu) { comp.setMenu(menu, false); } }, getSuffixConfig: function() { var me = this, layout = me.layout, owner = layout.owner, oid = owner.id; me.menu = new Ext.menu.Menu({ listeners: { scope: me, beforeshow: me.beforeMenuShow } }); me.menuTrigger = new Ext.button.Button({ id: oid + '-menu-trigger', cls: me.menuCls + '-after ' + Ext.baseCSSPrefix + 'toolbar-item', plain: owner.usePlainButtons, ownerCt: owner, ownerLayout: layout, iconCls: Ext.baseCSSPrefix + me.getOwnerType(owner) + '-more-icon', ui: owner.defaultButtonUI || 'default', menu: me.menu, showEmptyMenu: true, getSplitCls: function() { return ''; } }); return me.menuTrigger.getRenderTree(); }, getOverflowCls: function(direction) { return this.menuCls + '-body-' + direction; }, handleOverflow: function(ownerContext) { var me = this, layout = me.layout; me.showTrigger(ownerContext); if (layout.direction !== 'vertical') { me.menuTrigger.setLocalY((ownerContext.state.boxPlan.maxSize - me.menuTrigger[layout.names.getHeight]()) / 2); } return { reservedSpace: me.triggerTotalWidth }; }, captureChildElements: function() { var me = this, menuTrigger = me.menuTrigger, names = me.layout.names; if (menuTrigger.rendering) { menuTrigger.finishRender(); me.triggerTotalWidth = menuTrigger[names.getWidth]() + menuTrigger.el.getMargin(names.parallelMargins); } }, clearOverflow: function(ownerContext) { var me = this, items = me.menuItems, length = items.length, owner = me.layout.owner, asLayoutRoot = owner._asLayoutRoot, item, i; owner.suspendLayouts(); me.captureChildElements(); me.hideTrigger(); owner.resumeLayouts(); for (i = 0; i < length; i++) { item = items[i]; item.suspendLayouts(); item.show(); me.clearItem(item); item.resumeLayouts(asLayoutRoot); } items.length = 0; }, showTrigger: function(ownerContext) { var me = this, layout = me.layout, owner = layout.owner, names = layout.names, startProp = names.x, sizeProp = names.width, plan = ownerContext.state.boxPlan, available = plan.targetSize[sizeProp], childItems = ownerContext.childItems, menuTrigger = me.menuTrigger, menuItems = me.menuItems, childContext, comp, i, props, len; menuTrigger.suspendLayouts(); menuTrigger.show(); menuTrigger.resumeLayouts(me._asLayoutRoot); available -= me.triggerTotalWidth; owner.suspendLayouts(); for (i = 0 , len = menuItems.length; i < len; ++i) { me.clearItem(menuItems[i]); } menuItems.length = 0; for (i = 0 , len = childItems.length; i < len; i++) { childContext = childItems[i]; props = childContext.props; if (props[startProp] + props[sizeProp] > available) { comp = childContext.target; me.menuItems.push(comp); comp.hide(); } } owner.resumeLayouts(); }, hideTrigger: function() { var menuTrigger = this.menuTrigger; if (menuTrigger) { menuTrigger.hide(); } }, beforeMenuShow: function(menu) { var me = this, items = me.menuItems, i = 0, len = items.length, item, prev, needsSep = function(group, prev) { return group.isXType('buttongroup') && !(prev instanceof Ext.toolbar.Separator); }; menu.suspendLayouts(); menu.removeAll(false); 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); } menu.resumeLayouts(); }, createMenuConfig: function(component, hideOnClick) { var config = Ext.apply({}, component.initialConfig), group = component.toggleGroup; Ext.copyTo(config, component, [ 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu', 'tabIndex' ]); Ext.applyIf(config, { text: component.overflowText || component.text, hideOnClick: hideOnClick, destroyMenu: false, listeners: null }); if (component.isFormField) { config.value = component.getValue(); config.listeners = { change: function(c, newVal, oldVal) { component.setValue(newVal); } }; } else if (group || component.enableToggle) { Ext.apply(config, { hideOnClick: false, group: group, checked: component.pressed, handler: function(item, e) { component.onClick(e); } }); } if (component.isButton && !component.changeListenersAdded) { component.on({ textchange: this.onButtonAttrChange, iconchange: this.onButtonAttrChange, toggle: this.onButtonToggle }); component.changeListenersAdded = true; } delete config.margin; delete config.ownerCt; delete config.xtype; delete config.id; delete config.itemId; return config; }, onButtonAttrChange: function(btn) { var clone = btn.overflowClone; clone.suspendLayouts(); clone.setText(btn.text); clone.setIcon(btn.icon); clone.setIconCls(btn.iconCls); clone.resumeLayouts(true); }, onButtonToggle: function(btn, state) { if (btn.overflowClone.checked !== state) { btn.overflowClone.setChecked(state); } }, addComponentToMenu: function(menu, component) { var me = this, i, items, iLen; if (component instanceof Ext.toolbar.Fill) { return; } else if (component instanceof Ext.toolbar.Separator) { menu.add('-'); } else if (component.overflowClone) { menu.add(component.overflowClone); } else if (component.isComponent) { if (component.isXType('splitbutton')) { component.overflowClone = menu.add(me.createMenuConfig(component, true)); } else if (component.isXType('button')) { component.overflowClone = menu.add(me.createMenuConfig(component, !component.menu)); } else if (component.isXType('buttongroup')) { items = component.items.items; iLen = items.length; for (i = 0; i < iLen; i++) { me.addComponentToMenu(menu, items[i]); } } else { component.overflowClone = menu.add(Ext.create(Ext.getClassName(component), me.createMenuConfig(component))); } } }, destroy: function() { var trigger = this.menuTrigger; if (trigger && !this.layout.owner.items.contains(trigger)) { delete trigger.ownerCt; } Ext.destroy(this.menu, trigger); } }); Ext.define('Ext.form.field.HtmlEditor', { extend: 'Ext.form.FieldContainer', mixins: { field: 'Ext.form.field.Field' }, alias: 'widget.htmleditor', alternateClassName: 'Ext.form.HtmlEditor', requires: [ 'Ext.tip.QuickTipManager', 'Ext.picker.Color', 'Ext.layout.container.VBox', 'Ext.toolbar.Item', 'Ext.toolbar.Toolbar', 'Ext.util.Format', 'Ext.layout.component.field.HtmlEditor', 'Ext.util.TaskManager', 'Ext.layout.container.boxOverflow.Menu' ], focusable: true, componentLayout: 'htmleditor', textareaCls: Ext.baseCSSPrefix + 'htmleditor-textarea', componentTpl: [ '{beforeTextAreaTpl}', '', '{afterTextAreaTpl}', '{beforeIFrameTpl}', '', '{afterIFrameTpl}', { disableFormats: true } ], stretchInputElFixed: true, subTplInsertions: [ 'beforeTextAreaTpl', 'afterTextAreaTpl', 'beforeIFrameTpl', 'afterIFrameTpl', 'iframeAttrTpl', 'inputAttrTpl' ], 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' ], defaultValue: Ext.isOpera ? ' ' : '​', extraFieldBodyCls: Ext.baseCSSPrefix + 'html-editor-wrap', defaultButtonUI: 'default-toolbar', initialized: false, activated: false, sourceEditMode: false, iframePad: 3, hideMode: 'offsets', maskOnDisable: true, containerElCls: Ext.baseCSSPrefix + 'html-editor-container', reStripQuotes: /^['"]*|['"]*$/g, textAlignRE: /text-align:(.*?);/i, safariNonsenseRE: /\sclass="(?:Apple-style-span|Apple-tab-span|khtml-block-placeholder)"/gi, nonDigitsRE: /\D/g, initComponent: function() { var me = this; me.items = [ me.createToolbar(), me.createInputCmp() ]; me.layout = { type: 'vbox', align: 'stretch' }; if (me.value == null) { me.value = ''; } me.callParent(arguments); me.initField(); }, createInputCmp: function() { this.inputCmp = Ext.widget(this.getInputCmpCfg()); return this.inputCmp; }, getInputCmpCfg: function() { var me = this, id = me.id + '-inputCmp', data = { id: id, name: me.name, textareaCls: me.textareaCls + ' ' + Ext.baseCSSPrefix + 'hidden', value: me.value, iframeName: Ext.id(), iframeSrc: Ext.SSL_SECURE_URL, iframeCls: Ext.baseCSSPrefix + 'htmleditor-iframe' }; me.getInsertionRenderData(data, me.subTplInsertions); return { flex: 1, xtype: 'component', tpl: me.getTpl('componentTpl'), childEls: [ 'iframeEl', 'textareaEl' ], id: id, cls: Ext.baseCSSPrefix + 'html-editor-input', data: data }; }, createToolbar: function() { this.toolbar = Ext.widget(this.getToolbarCfg()); return this.toolbar; }, getToolbarCfg: function() { var me = this, items = [], i, tipsEnabled = Ext.quickTipsActive && Ext.tip.QuickTipManager.isEnabled(), baseCSSPrefix = Ext.baseCSSPrefix, fontSelectItem, undef; function btn(id, toggle, handler) { return { itemId: id, cls: baseCSSPrefix + 'btn-icon', iconCls: baseCSSPrefix + 'edit-' + id, enableToggle: toggle !== false, scope: me, handler: handler || me.relayBtnCmd, clickEvent: 'mousedown', tooltip: tipsEnabled ? me.buttonTips[id] || undef : undef, overflowText: me.buttonTips[id].title || undef, tabIndex: -1 }; } if (me.enableFont && !Ext.isSafari2) { fontSelectItem = Ext.widget('component', { itemId: 'fontSelect', renderTpl: [ '' ], childEls: [ 'selectEl' ], afterRender: function() { me.fontSelect = this.selectEl; Ext.Component.prototype.afterRender.apply(this, arguments); }, onDisable: function() { var selectEl = this.selectEl; if (selectEl) { selectEl.dom.disabled = true; } Ext.Component.prototype.onDisable.apply(this, arguments); }, onEnable: function() { var selectEl = this.selectEl; if (selectEl) { selectEl.dom.disabled = false; } Ext.Component.prototype.onEnable.apply(this, arguments); }, listeners: { change: function() { me.win.focus(); me.relayCmd('fontName', me.fontSelect.dom.value); me.deferFocus(); }, element: 'selectEl' } }); items.push(fontSelectItem, '-'); } if (me.enableFormat) { items.push(btn('bold'), btn('italic'), btn('underline')); } if (me.enableFontSize) { items.push('-', btn('increasefontsize', false, me.adjustFont), btn('decreasefontsize', false, me.adjustFont)); } if (me.enableColors) { items.push('-', { itemId: 'forecolor', cls: baseCSSPrefix + 'btn-icon', iconCls: baseCSSPrefix + 'edit-forecolor', overflowText: me.buttonTips.forecolor.title, tooltip: tipsEnabled ? me.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.relayCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#' + color : color); this.up('menu').hide(); } } ] }) }, { itemId: 'backcolor', cls: baseCSSPrefix + 'btn-icon', iconCls: baseCSSPrefix + 'edit-backcolor', overflowText: me.buttonTips.backcolor.title, tooltip: tipsEnabled ? me.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.relayCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE || Ext.isOpera ? '#' + color : color); } this.up('menu').hide(); } } ] }) }); } if (me.enableAlignments) { items.push('-', btn('justifyleft'), btn('justifycenter'), btn('justifyright')); } if (!Ext.isSafari2) { if (me.enableLinks) { items.push('-', btn('createlink', false, me.createLink)); } if (me.enableLists) { items.push('-', btn('insertorderedlist'), btn('insertunorderedlist')); } if (me.enableSourceEdit) { items.push('-', btn('sourceedit', true, function() { me.toggleSourceEdit(!me.sourceEditMode); })); } } for (i = 0; i < items.length; i++) { if (items[i].itemId !== 'sourceedit') { items[i].disabled = true; } } return { xtype: 'toolbar', defaultButtonUI: me.defaultButtonUI, cls: Ext.baseCSSPrefix + 'html-editor-tb', enableOverflow: true, items: items, listeners: { click: function(e) { e.preventDefault(); }, element: 'el' } }; }, getMaskTarget: function() { return Ext.isGecko ? this.inputCmp.el : this.bodyEl; }, setReadOnly: function(readOnly) { var me = this, textareaEl = me.textareaEl, iframeEl = me.iframeEl, body; me.readOnly = readOnly; if (textareaEl) { textareaEl.dom.readOnly = readOnly; } 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); } }, getDocMarkup: function() { var me = this, h = me.iframeEl.getHeight() - me.iframePad * 2; return Ext.String.format('' + '', me.iframePad, h, me.defaultFont); }, getEditorBody: function() { var doc = this.getDoc(); return doc.body || doc.documentElement; }, getDoc: function() { return this.iframeEl.dom.contentDocument || this.getWin().document; }, getWin: function() { return this.iframeEl.dom.contentWindow || window.frames[this.iframeEl.dom.name]; }, initDefaultFont: function() { var me = this, selIdx = 0, fonts, font, select, option, i, len, lower; if (!me.defaultFont) { font = me.textareaEl.getStyle('font-family'); font = Ext.String.capitalize(font.split(',')[0]); fonts = Ext.Array.clone(me.fontFamilies); Ext.Array.include(fonts, font); fonts.sort(); me.defaultFont = font; select = me.down('#fontSelect').selectEl.dom; for (i = 0 , len = fonts.length; i < len; ++i) { font = fonts[i]; lower = font.toLowerCase(); option = new Option(font, lower); if (font === me.defaultFont) { selIdx = i; } option.style.fontFamily = lower; if (Ext.isIE) { select.add(option); } else { select.options.add(option); } } select.options[selIdx].selected = true; } }, isEqual: function(value1, value2) { return this.isEqualAsString(value1, value2); }, afterRender: function() { var me = this, inputCmp = me.inputCmp; me.callParent(arguments); me.iframeEl = inputCmp.iframeEl; me.textareaEl = inputCmp.textareaEl; me.inputEl = me.iframeEl; if (me.enableFont) { me.initDefaultFont(); } me.monitorTask = Ext.TaskManager.start({ run: me.checkDesignMode, scope: me, interval: 100 }); }, initFrameDoc: function() { var me = this, doc, task; Ext.TaskManager.stop(me.monitorTask); 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); }, checkDesignMode: function() { var me = this, doc = me.getDoc(); if (doc && (!doc.editorInitialized || me.getDesignMode() !== 'on')) { me.initFrameDoc(); } }, 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'; } }, getDesignMode: function() { var doc = this.getDoc(); return !doc ? '' : String(doc.designMode).toLowerCase(); }, disableItems: function(disabled) { var items = this.getToolbar().items.items, i, iLen = items.length, item; for (i = 0; i < iLen; i++) { item = items[i]; if (item.getItemId() !== 'sourceedit') { item.setDisabled(disabled); } } }, 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; } me.sourceEditMode = sourceEditMode; if (btn.pressed !== sourceEditMode) { btn.toggle(sourceEditMode); } if (sourceEditMode) { me.disableItems(true); me.syncValue(); iframe.addCls(hiddenCls); textarea.removeCls(hiddenCls); textarea.dom.removeAttribute('tabindex'); textarea.focus(); me.inputEl = textarea; } else { if (me.initialized) { me.disableItems(me.readOnly); } me.pushValue(); iframe.removeCls(hiddenCls); textarea.addCls(hiddenCls); textarea.dom.setAttribute('tabindex', -1); me.deferFocus(); me.inputEl = iframe; } me.fireEvent('editmodechange', me, sourceEditMode); me.updateLayout(); }, createLink: function() { var url = prompt(this.createLinkText, this.defaultLinkValue); if (url && url !== 'http:/' + '/') { this.relayCmd('createlink', url); } }, clearInvalid: Ext.emptyFn, setValue: function(value) { var me = this, textarea = me.textareaEl; if (value === null || value === undefined) { value = ''; } if (me.value !== value) { if (textarea) { textarea.dom.value = value; } me.pushValue(); if (!me.rendered && me.inputCmp) { me.inputCmp.data.value = value; } me.mixins.field.setValue.call(me, value); } return me; }, cleanHtml: function(html) { html = String(html); if (Ext.isWebKit) { html = html.replace(this.safariNonsenseRE, ''); } if (html.charCodeAt(0) === parseInt(this.defaultValue.replace(this.nonDigitsRE, ''), 10)) { html = html.substring(1); } return html; }, syncValue: function() { var me = this, body, changed, html, bodyStyle, match, textElDom; if (me.initialized) { body = me.getEditorBody(); html = body.innerHTML; textElDom = me.textareaEl.dom; if (Ext.isWebKit) { bodyStyle = body.getAttribute('style'); match = bodyStyle.match(me.textAlignRE); if (match && match[1]) { html = '
    ' + html + '
    '; } } html = me.cleanHtml(html); if (me.fireEvent('beforesync', me, html) !== false) { if (Ext.isGecko && textElDom.value === '' && html === '
    ') { html = ''; } if (textElDom.value !== html) { textElDom.value = html; changed = true; } me.fireEvent('sync', me, html); if (changed) { me.checkChange(); } } } }, 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; }, 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); } } }, focus: function(selectText, delay) { var me = this, value, focusEl; if (delay) { if (!me.focusTask) { me.focusTask = new Ext.util.DelayedTask(me.focus); } me.focusTask.delay(Ext.isNumber(delay) ? delay : 10, null, me, [ selectText, false ]); } else { if (selectText) { if (me.textareaEl && me.textareaEl.dom) { value = me.textareaEl.dom.value; } if (value && value.length) { me.execCmd('selectall', true); } } focusEl = me.getFocusEl(); if (focusEl && focusEl.focus) { focusEl.focus(); } } return me; }, initEditor: function() { var me = this, dbody, ss, doc, docEl, fn; if (me.destroying || me.isDestroyed) { return; } dbody = me.getEditorBody(); if (!dbody) { setTimeout(function() { me.initEditor(); }, 10); return; } ss = me.textareaEl.getStyle([ 'font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color' ]); ss['background-attachment'] = 'fixed'; dbody.bgProperties = 'fixed'; Ext.DomHelper.applyStyles(dbody, ss); doc = me.getDoc(); docEl = Ext.get(doc); if (docEl) { try { docEl.clearListeners(); } catch (e) {} fn = me.onEditorEvent.bind(me); docEl.on({ mousedown: fn, dblclick: fn, click: fn, keyup: fn, delegated: false, buffer: 100 }); fn = me.onRelayedEvent; docEl.on({ mousedown: fn, mousemove: fn, mouseup: fn, click: fn, dblclick: fn, delegated: false, scope: me }); if (Ext.isGecko) { docEl.on('keypress', me.applyCommand, me); } if (me.fixKeys) { docEl.on('keydown', me.fixKeys, me, { delegated: false }); } if (me.fixKeysAfter) { docEl.on('keyup', me.fixKeysAfter, me, { delegated: false }); } if (Ext.isIE9) { Ext.get(doc.documentElement).on('focus', me.focus, me); } if (Ext.isIE8) { docEl.on('focusout', function() { me.savedSelection = doc.selection.type !== 'None' ? doc.selection.createRange() : null; }, me); docEl.on('focusin', function() { if (me.savedSelection) { me.savedSelection.select(); } }, me); } Ext.getWin().on('beforeunload', me.beforeDestroy, me); doc.editorInitialized = true; me.initialized = true; me.pushValue(); me.setReadOnly(me.readOnly); me.fireEvent('initialize', me); } }, beforeDestroy: function() { var me = this, monitorTask = me.monitorTask, doc, prop; if (monitorTask) { Ext.TaskManager.stop(monitorTask); } if (me.rendered) { Ext.getWin().un(me.beforeDestroy, me); doc = me.getDoc(); if (doc) { Ext.get(doc).destroy(); if (doc.hasOwnProperty) { for (prop in doc) { try { if (doc.hasOwnProperty(prop)) { delete doc[prop]; } } catch (e) {} } } } delete me.iframeEl; delete me.textareaEl; delete me.toolbar; delete me.inputCmp; } me.callParent(); }, onRelayedEvent: function(event) { var iframeEl = this.iframeEl, iframeXY = Ext.fly(iframeEl).getTrueXY(), originalEventXY = event.getXY(), eventXY = event.getXY(); event.xy = [ iframeXY[0] + eventXY[0], iframeXY[1] + eventXY[1] ]; event.injectEvent(iframeEl); event.xy = originalEventXY; }, 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 && !me.getValue().length) { 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); }, 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; } size = Math.max(1, size + adjust) + (isSafari ? 'px' : 0); } this.relayCmd('FontSize', size); }, onEditorEvent: function() { this.updateToolbar(); }, updateToolbar: function() { var me = this, i, l, btns, doc, name, queriedName, fontSelect, toolbarSubmenus; if (me.readOnly) { return; } if (!me.activated) { me.onFirstFocus(); return; } btns = me.getToolbar().items.map; doc = me.getDoc(); if (me.enableFont && !Ext.isSafari2) { queriedName = doc.queryCommandValue('fontName'); name = (queriedName ? queriedName.split(",")[0].replace(me.reStripQuotes, '') : me.defaultFont).toLowerCase(); fontSelect = me.fontSelect.dom; if (name !== fontSelect.value || name !== queriedName) { fontSelect.value = name; } } function updateButtons() { var state; for (i = 0 , l = arguments.length , name; i < l; i++) { name = arguments[i]; try { state = doc.queryCommandState(name); } catch (e) { state = false; } btns[name].toggle(state); } } if (me.enableFormat) { updateButtons('bold', 'italic', 'underline'); } if (me.enableAlignments) { updateButtons('justifyleft', 'justifycenter', 'justifyright'); } if (!Ext.isSafari2 && me.enableLists) { updateButtons('insertorderedlist', 'insertunorderedlist'); } toolbarSubmenus = me.toolbar.query('menu'); for (i = 0; i < toolbarSubmenus.length; i++) { toolbarSubmenus[i].hide(); } me.syncValue(); }, relayBtnCmd: function(btn) { this.relayCmd(btn.getItemId()); }, relayCmd: function(cmd, value) { Ext.defer(function() { var me = this; if (!this.isDestroyed) { me.win.focus(); me.execCmd(cmd, value); me.updateToolbar(); } }, 10, this); }, execCmd: function(cmd, value) { var me = this, doc = me.getDoc(); doc.execCommand(cmd, false, (value === undefined ? null : value)); me.syncValue(); }, 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; } if (cmd) { me.win.focus(); me.execCmd(cmd); me.deferFocus(); e.preventDefault(); } } } }, insertAtCursor: function(text) { var me = this, win = me.getWin(), doc = me.getDoc(), sel, range, el, frag, node, lastNode, firstNode; if (me.activated) { win.focus(); if (win.getSelection) { sel = win.getSelection(); if (sel.getRangeAt && sel.rangeCount) { range = sel.getRangeAt(0); range.deleteContents(); el = doc.createElement("div"); el.innerHTML = text; frag = doc.createDocumentFragment(); while ((node = el.firstChild)) { lastNode = frag.appendChild(node); } firstNode = frag.firstChild; range.insertNode(frag); if (lastNode) { range = range.cloneRange(); range.setStartAfter(lastNode); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); } } } else if (doc.selection && sel.type !== 'Control') { sel = doc.selection; range = sel.createRange(); range.collapse(true); sel.createRange().pasteHTML(text); } me.deferFocus(); } }, fixKeys: (function() { var tag; if (Ext.isIE) { return function(e) { var me = this, k = e.getKey(), doc = me.getDoc(), readOnly = me.readOnly, range, target; if (k === e.TAB) { e.stopEvent(); if (!readOnly) { range = doc.selection.createRange(); if (range) { if (range.collapse) { range.collapse(true); range.pasteHTML('    '); } me.deferFocus(); } } } else if (k === e.ENTER) { if (!readOnly) { if (Ext.isIE10m) { range = doc.selection.createRange(); if (range) { target = range.parentElement(); if (!target || target.tagName.toLowerCase() !== 'li') { e.stopEvent(); range.pasteHTML('
    '); range.collapse(false); range.select(); } } } else { range = doc.getSelection().getRangeAt(0); if (range && range.commonAncestorContainer.parentNode.tagName.toLowerCase() !== 'li') { e.stopEvent(); tag = doc.createElement('div'); range.insertNode(tag); } } } } }; } if (Ext.isOpera) { return function(e) { var me = this, k = e.getKey(), readOnly = me.readOnly; if (k === e.TAB) { e.stopEvent(); if (!readOnly) { me.win.focus(); me.execCmd('InsertHTML', '    '); me.deferFocus(); } } }; } return null; }()), fixKeysAfter: (function() { if (Ext.isIE) { return function(e) { var me = this, k = e.getKey(), doc = me.getDoc(), readOnly = me.readOnly, innerHTML; if (!readOnly && (k === e.BACKSPACE || k === e.DELETE)) { innerHTML = doc.body.innerHTML; if (innerHTML === '

     

    ' || innerHTML === '

     

    ') { doc.body.innerHTML = ''; } } }; } return null; }()), getToolbar: function() { return this.toolbar; }, 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' } }, privates: { deferFocus: function() { this.focus(false, true); }, getFocusEl: function() { return this.sourceEditMode ? this.textareaEl : this.iframeEl; } } }); Ext.define('Ext.form.field.Tag', { extend: 'Ext.form.field.ComboBox', requires: [ 'Ext.selection.Model', 'Ext.data.Store', 'Ext.data.ChainedStore' ], xtype: 'tagfield', noWrap: false, multiSelect: true, delimiter: ',', tipTpl: undefined, forceSelection: true, createNewOnEnter: false, createNewOnBlur: false, encodeSubmitValue: false, triggerOnClick: true, stacked: false, filterPickList: false, grow: true, growMin: false, growMax: false, selectOnFocus: true, fieldSubTpl: [ '
    ', '
      ', '
    • ', '
      {emptyText}
      ', 'name="{name}" ', ' value="{[Ext.util.Format.htmlEncode(values.value)]}"', 'size="{size}" ', 'tabindex="{tabIdx}" ', ' disabled="disabled"', 'class="' + Ext.baseCSSPrefix + 'tagfield-input-field {inputElCls}" autocomplete="off">', '
    • ', '
    ', '
    ', { disableFormats: true } ], extraFieldBodyCls: Ext.baseCSSPrefix + 'tagfield-body', childEls: [ 'listWrapper', 'itemList', 'inputEl', 'inputElCt', 'emptyEl' ], emptyInputCls: Ext.baseCSSPrefix + 'tagfield-emptyinput', clearValueOnEmpty: false, tagItemCls: Ext.baseCSSPrefix + 'tagfield-item', tagItemTextCls: Ext.baseCSSPrefix + 'tagfield-item-text', tagItemCloseCls: Ext.baseCSSPrefix + 'tagfield-item-close', tagItemSelector: '.' + Ext.baseCSSPrefix + 'tagfield-item', tagItemCloseSelector: '.' + Ext.baseCSSPrefix + 'tagfield-item-close', tagSelectedCls: Ext.baseCSSPrefix + 'tagfield-item-selected', initComponent: function() { var me = this, typeAhead = me.typeAhead, delimiter = me.delimiter; if (typeAhead && !me.editable) { Ext.Error.raise('If typeAhead is enabled the combo must be editable: true -- please change one of those settings.'); } if (me.createNewOnEnter || me.createNewOnBlur) { me.forceSelection = false; } me.typeAhead = false; if (me.value == null) { me.value = []; } me.selectionModel = new Ext.selection.Model({ mode: 'MULTI', onSelectChange: function(record, isSelected, suppressEvent, commitFn) { commitFn(); }, listeners: { scope: me, selectionchange: me.onSelectionChange, focuschange: me.onFocusChange } }); me.callParent(); me.typeAhead = typeAhead; if (delimiter && me.multiSelect) { me.delimiterRegexp = new RegExp(Ext.String.escapeRegex(delimiter)); } }, initEvents: function() { var me = this, inputEl = me.inputEl; me.callParent(arguments); if (!me.enableKeyEvents) { inputEl.on('keydown', me.onKeyDown, me); inputEl.on('keyup', me.onKeyUp, me); } me.listWrapper.on('click', me.onItemListClick, me); }, isValid: function() { var me = this, disabled = me.disabled, validate = me.forceValidation || !disabled; return validate ? me.validateValue(me.getValue()) : disabled; }, onBindStore: function(store) { var me = this; me.callParent([ store ]); if (store) { me.valueStore = new Ext.data.Store({ model: store.getModel(), useModelWarning: false }); me.selectionModel.bindStore(me.valueStore); if (me.filterPickList) { me.listFilter = new Ext.util.Filter({ scope: me, filterFn: me.filterPicked }); me.changingFilters = true; store.filter(me.listFilter); me.changingFilters = false; } } }, filterPicked: function(rec) { return !this.valueCollection.contains(rec); }, onUnbindStore: function(store) { var me = this, valueStore = me.valueStore, picker = me.picker; if (picker) { picker.bindStore(null); } if (valueStore) { valueStore.destroy(); me.valueStore = null; } if (me.filterPickList && !store.isDestroyed) { me.changingFilters = true; store.removeFilter(me.listFilter); me.changingFilters = false; } me.callParent(arguments); }, onValueCollectionEndUpdate: function() { var me = this, pickedRecords = me.valueCollection.items, valueStore = me.valueStore; if (me.isSelectionUpdating()) { return; } if (me.filterPickList) { me.changingFilters = true; me.store.filter(me.listFilter); me.changingFilters = false; } me.callParent(); Ext.suspendLayouts(); if (valueStore) { valueStore.suspendEvents(); valueStore.loadRecords(pickedRecords); valueStore.resumeEvents(); } Ext.resumeLayouts(true); me.alignPicker(); }, checkValueOnDataChange: Ext.emptyFn, onSelectionChange: function(selModel, selectedRecs) { this.applyMultiselectItemMarkup(); this.fireEvent('valueselectionchange', this, selectedRecs); }, onFocusChange: function(selectionModel, oldFocused, newFocused) { this.fireEvent('valuefocuschange', this, oldFocused, newFocused); }, onDestroy: function() { this.selectionModel = Ext.destroy(this.selectionModel); this.callParent(arguments); }, getSubTplData: function(fieldData) { var me = this, data = me.callParent(arguments), emptyText = me.emptyText, emptyInputCls = me.emptyInputCls, isEmpty = emptyText && data.value.length < 1, growMin = me.growMin, growMax = me.growMax, wrapperStyle = ''; data.value = ''; data.emptyText = isEmpty ? emptyText : ''; data.emptyCls = isEmpty ? me.emptyCls : emptyInputCls; data.inputElCls = isEmpty ? emptyInputCls : ''; data.itemListCls = ''; if (me.grow) { if (Ext.isNumber(growMin) && growMin > 0) { wrapperStyle += 'min-height:' + growMin + 'px;'; } if (Ext.isNumber(growMax) && growMax > 0) { wrapperStyle += 'max-height:' + growMax + 'px;'; } } data.wrapperStyle = wrapperStyle; if (me.stacked === true) { data.itemListCls += ' ' + Ext.baseCSSPrefix + 'tagfield-stacked'; } if (!me.multiSelect) { data.itemListCls += ' ' + Ext.baseCSSPrefix + 'tagfield-singleselect'; } return data; }, afterRender: function() { var me = this, inputEl = me.inputEl; if (Ext.supports.Placeholder && inputEl && me.emptyText) { inputEl.dom.removeAttribute('placeholder'); } me.applyMultiselectItemMarkup(); me.callParent(arguments); }, findRecord: function(field, value) { var matches = this.getStore().queryRecords(field, value); return matches.length ? matches[0] : false; }, getCursorPosition: function() { var cursorPos; if (document.selection) { cursorPos = document.selection.createRange(); cursorPos.collapse(true); cursorPos.moveStart('character', -this.inputEl.dom.value.length); cursorPos = cursorPos.text.length; } else { cursorPos = this.inputEl.dom.selectionStart; } return cursorPos; }, hasSelectedText: function() { var inputEl = this.inputEl.dom, sel, range; if (document.selection) { sel = document.selection; range = sel.createRange(); return (range.parentElement() === inputEl); } else { return inputEl.selectionStart !== inputEl.selectionEnd; } }, onKeyDown: function(e) { var me = this, key = e.getKey(), inputEl = me.inputEl, rawValue = inputEl.dom.value, valueCollection = me.valueCollection, selModel = me.selectionModel, stopEvent = false, lastSelectionIndex; if (me.readOnly || me.disabled || !me.editable) { return; } if (valueCollection.getCount() > 0 && (rawValue === '' || (me.getCursorPosition() === 0 && !me.hasSelectedText()))) { lastSelectionIndex = (selModel.getCount() > 0) ? valueCollection.indexOf(selModel.getLastSelected()) : -1; if (key === e.BACKSPACE || key === e.DELETE) { if (lastSelectionIndex > -1) { if (selModel.getCount() > 1) { lastSelectionIndex = -1; } valueCollection.remove(selModel.getSelection()); } else { valueCollection.remove(valueCollection.last()); } selModel.clearSelections(); if (lastSelectionIndex > 0) { selModel.select(lastSelectionIndex - 1); } else if (valueCollection.getCount()) { selModel.select(valueCollection.last()); } stopEvent = true; } else if (key === e.RIGHT || key === e.LEFT) { if (lastSelectionIndex === -1 && key === e.LEFT) { selModel.select(valueCollection.last()); stopEvent = true; } else if (lastSelectionIndex > -1) { if (key === e.RIGHT) { if (lastSelectionIndex < (valueCollection.getCount() - 1)) { selModel.select(lastSelectionIndex + 1, e.shiftKey); stopEvent = true; } else if (!e.shiftKey) { selModel.deselectAll(); stopEvent = true; } } else if (key === e.LEFT && (lastSelectionIndex > 0)) { selModel.select(lastSelectionIndex - 1, e.shiftKey); stopEvent = true; } } } else if (key === e.A && e.ctrlKey) { selModel.selectAll(); stopEvent = e.A; } } if (stopEvent) { me.preventKeyUpEvent = stopEvent; e.stopEvent(); return; } if (me.isExpanded && key === e.ENTER && me.picker.highlightedItem) { me.preventKeyUpEvent = true; } if (me.enableKeyEvents) { me.callParent(arguments); } if (!e.isSpecialKey() && !e.hasModifier()) { selModel.deselectAll(); } }, onKeyUp: function(e, t) { var me = this, inputEl = me.inputEl, rawValue = inputEl.dom.value, preventKeyUpEvent = me.preventKeyUpEvent; if (me.preventKeyUpEvent) { e.stopEvent(); if (preventKeyUpEvent === true || e.getKey() === preventKeyUpEvent) { delete me.preventKeyUpEvent; } return; } if (me.multiSelect && me.delimiterRegexp && me.delimiterRegexp.test(rawValue) || (me.createNewOnEnter && e.getKey() === e.ENTER)) { rawValue = Ext.Array.clean(rawValue.split(me.delimiterRegexp)); inputEl.dom.value = ''; me.setValue(me.valueStore.getRange().concat(rawValue)); inputEl.focus(); } me.callParent([ e, t ]); }, onTypeAhead: function() { var me = this, displayField = me.displayField, inputElDom = me.inputEl.dom, boundList = me.getPicker(), record = me.getStore().findRecord(displayField, inputElDom.value), newValue, len, selStart; if (record) { newValue = record.get(displayField); len = newValue.length; selStart = inputElDom.value.length; boundList.highlightItem(boundList.getNode(record)); if (selStart !== 0 && selStart !== len) { inputElDom.value = newValue; me.selectText(selStart, newValue.length); } } }, onItemListClick: function(e) { var me = this, selectionModel = me.selectionModel, itemEl = e.getTarget(me.tagItemSelector), closeEl = itemEl ? e.getTarget(me.tagItemCloseSelector) : false; if (me.readOnly || me.disabled) { return; } e.stopPropagation(); if (itemEl) { if (closeEl) { me.removeByListItemNode(itemEl); if (me.valueStore.getCount() > 0) { me.fireEvent('select', me, me.valueStore.getRange()); } } else { me.toggleSelectionByListItemNode(itemEl, e.shiftKey); } if (!Ext.supports.TouchEvents) { me.inputEl.focus(); } } else { if (selectionModel.getCount() > 0) { selectionModel.deselectAll(); } me.inputEl.focus(); if (me.triggerOnClick) { me.onTriggerClick(); } } }, getMultiSelectItemMarkup: function() { var me = this, cssPrefix = Ext.baseCSSPrefix, valueField = me.valueField; if (!me.multiSelectItemTpl) { if (!me.labelTpl) { me.labelTpl = '{' + me.displayField + '}'; } me.labelTpl = me.getTpl('labelTpl'); if (me.tipTpl) { me.tipTpl = me.getTpl('tipTpl'); } me.multiSelectItemTpl = new Ext.XTemplate([ '', '
  • ', ' ' + me.tagSelectedCls, '', '{%', 'values = values.data;', '%}', me.tipTpl ? '" data-qtip="{[this.getTip(values)]}">' : '">', '
    {[this.getItemLabel(values)]}
    ', '
    ', '
  • ', '
    ', { isSelected: function(rec) { return me.selectionModel.isSelected(rec); }, getItemLabel: function(values) { return Ext.String.htmlEncode(me.labelTpl.apply(values)); }, getTip: function(values) { return Ext.String.htmlEncode(me.tipTpl.apply(values)); }, strict: true } ]); } if (!me.multiSelectItemTpl.isTemplate) { me.multiSelectItemTpl = this.getTpl('multiSelectItemTpl'); } return me.multiSelectItemTpl.apply(me.valueCollection.getRange()); }, applyMultiselectItemMarkup: function() { var me = this, itemList = me.itemList; if (itemList) { itemList.select('.' + Ext.baseCSSPrefix + 'tagfield-item').destroy(); me.inputElCt.insertHtml('beforeBegin', me.getMultiSelectItemMarkup()); me.autoSize(); } }, getRecordByListItemNode: function(itemEl) { return this.valueCollection.items[Number(itemEl.getAttribute('data-selectionIndex'))]; }, toggleSelectionByListItemNode: function(itemEl, keepExisting) { var me = this, rec = me.getRecordByListItemNode(itemEl), selModel = me.selectionModel; if (rec) { if (selModel.isSelected(rec)) { selModel.deselect(rec); } else { selModel.select(rec, keepExisting); } } }, removeByListItemNode: function(itemEl) { var me = this, rec = me.getRecordByListItemNode(itemEl); if (rec) { me.pickerSelectionModel.deselect(rec); } }, getDisplayValue: function() { return this.getRawValue(); }, getRawValue: function() { var me = this, records = me.getValueRecords(), values = [], i, len; for (i = 0 , len = records.length; i < len; i++) { values.push(records[i].data[me.displayField]); } return values.join(','); }, setRawValue: function(value) { return; }, removeValue: function(value) { var me = this, valueCollection = me.valueCollection, len, i, item, toRemove = []; if (value) { value = Ext.Array.from(value); for (i = 0 , len = value.length; i < len; ++i) { item = value[i]; if (!item.isModel) { item = valueCollection.byValue.get(item); } if (item) { toRemove.push(item); } } me.valueCollection.beginUpdate(); me.pickerSelectionModel.deselect(toRemove); me.valueCollection.endUpdate(); } }, setValue: function(value, add, skipLoad) { var me = this, valueStore = me.valueStore, valueField = me.valueField, unknownValues = [], store = me.store, record, len, i, valueRecord, cls, params; if (Ext.isEmpty(value)) { value = null; } if (Ext.isString(value) && me.multiSelect) { value = value.split(me.delimiter); } value = Ext.Array.from(value, true); for (i = 0 , len = value.length; i < len; i++) { record = value[i]; if (!record || !record.isModel) { valueRecord = valueStore.findExact(valueField, record); if (valueRecord > -1) { value[i] = valueStore.getAt(valueRecord); } else { valueRecord = me.findRecord(valueField, record); if (!valueRecord) { if (me.forceSelection) { unknownValues.push(record); } else { valueRecord = {}; valueRecord[me.valueField] = record; valueRecord[me.displayField] = record; cls = me.valueStore.getModel(); valueRecord = new cls(valueRecord); } } if (valueRecord) { value[i] = valueRecord; } } } } if (!store.isEmptyStore && skipLoad !== true && unknownValues.length > 0 && me.queryMode === 'remote') { params = {}; params[me.valueParam || me.valueField] = unknownValues.join(me.delimiter); store.load({ params: params, callback: function() { if (me.itemList) { me.itemList.unmask(); } me.setValue(value, add, true); me.autoSize(); me.lastQuery = false; } }); return false; } if (!me.multiSelect && value.length > 0) { for (i = value.length - 1; i >= 0; i--) { if (value[i].isModel) { value = value[i]; break; } } if (Ext.isArray(value)) { value = value[value.length - 1]; } } return me.callParent([ value, add ]); }, updateValue: function() { var me = this, valueArray = me.valueCollection.getRange(), len = valueArray.length, i; for (i = 0; i < len; i++) { valueArray[i] = valueArray[i].get(me.valueField); } me.setHiddenValue(valueArray); me.value = me.multiSelect ? valueArray : valueArray[0]; if (!Ext.isDefined(me.value)) { me.value = undefined; } me.applyMultiselectItemMarkup(); me.checkChange(); }, getValueRecords: function() { return this.valueCollection.getRange(); }, getSubmitData: function() { var me = this, val = me.callParent(arguments); if (me.multiSelect && me.encodeSubmitValue && val && val[me.name]) { val[me.name] = Ext.encode(val[me.name]); } return val; }, assertValue: function() { var me = this, rawValue = me.inputEl.dom.value, rec = !Ext.isEmpty(rawValue) ? me.findRecordByDisplay(rawValue) : false, value = false; if (!rec && !me.forceSelection && me.createNewOnBlur && !Ext.isEmpty(rawValue)) { value = rawValue; } else if (rec) { value = rec; } if (value) { me.addValue(value); } me.inputEl.dom.value = ''; me.collapse(); }, isEqual: function(v1, v2) { var fromArray = Ext.Array.from, valueField = this.valueField, i, len, t1, t2; v1 = fromArray(v1); v2 = fromArray(v2); len = v1.length; if (len !== v2.length) { return false; } for (i = 0; i < len; i++) { t1 = v1[i].isModel ? v1[i].get(valueField) : v1[i]; t2 = v2[i].isModel ? v2[i].get(valueField) : v2[i]; if (t1 !== t2) { return false; } } return true; }, applyEmptyText: function() { var me = this, emptyText = me.emptyText, emptyEl = me.emptyEl, inputEl = me.inputEl, listWrapper = me.listWrapper, emptyCls = me.emptyCls, emptyInputCls = me.emptyInputCls, isEmpty; if (me.rendered && emptyText) { isEmpty = Ext.isEmpty(me.value) && !me.hasFocus; if (isEmpty) { inputEl.dom.value = ''; emptyEl.setHtml(emptyText); emptyEl.addCls(emptyCls); emptyEl.removeCls(emptyInputCls); listWrapper.addCls(emptyCls); inputEl.addCls(emptyInputCls); } else { emptyEl.addCls(emptyInputCls); emptyEl.removeCls(emptyCls); listWrapper.removeCls(emptyCls); inputEl.removeCls(emptyInputCls); } me.autoSize(); } }, preFocus: function() { var me = this, inputEl = me.inputEl, isEmpty = inputEl.dom.value === ''; me.emptyEl.addCls(me.emptyInputCls); me.emptyEl.removeCls(me.emptyCls); me.listWrapper.removeCls(me.emptyCls); me.inputEl.removeCls(me.emptyInputCls); if (me.selectOnFocus || isEmpty) { inputEl.dom.select(); } }, onFocus: function() { var me = this, focusCls = me.focusCls, itemList = me.itemList; if (focusCls && itemList) { itemList.addCls(focusCls); } me.callParent(arguments); }, onBlur: function() { var me = this, focusCls = me.focusCls, itemList = me.itemList; if (focusCls && itemList) { itemList.removeCls(focusCls); } me.callParent(arguments); }, renderActiveError: function() { var me = this, invalidCls = me.invalidCls, itemList = me.itemList, hasError = me.hasActiveError(); if (invalidCls && itemList) { itemList[hasError ? 'addCls' : 'removeCls'](me.invalidCls + '-field'); } me.callParent(arguments); }, autoSize: function() { var me = this; if (me.grow && me.rendered) { me.autoSizing = true; me.updateLayout(); } return me; }, afterComponentLayout: function() { var me = this, height; if (me.autoSizing) { height = me.getHeight(); if (height !== me.lastInputHeight) { if (me.isExpanded) { me.alignPicker(); } me.fireEvent('autosize', me, height); me.lastInputHeight = height; me.autoSizing = false; } } } }); Ext.define('Ext.picker.Time', { extend: 'Ext.view.BoundList', alias: 'widget.timepicker', requires: [ 'Ext.data.Store', 'Ext.Date' ], config: { store: true }, statics: { createStore: function(format, increment) { var dateUtil = Ext.Date, clearTime = dateUtil.clearTime, initDate = this.prototype.initDate, times = [], min = clearTime(new Date(initDate[0], initDate[1], initDate[2])), max = dateUtil.add(clearTime(new Date(initDate[0], initDate[1], initDate[2])), 'mi', (24 * 60) - 1); while (min <= max) { times.push({ disp: dateUtil.dateFormat(min, format), date: min }); min = dateUtil.add(min, 'mi', increment); } return new Ext.data.Store({ model: Ext.picker.Time.prototype.modelType, data: times }); } }, increment: 15, format: "g:i A", displayField: 'disp', initDate: [ 2008, 0, 1 ], componentCls: Ext.baseCSSPrefix + 'timepicker', loadMask: false, initComponent: function() { var me = this, dateUtil = Ext.Date, clearTime = dateUtil.clearTime, initDate = me.initDate; me.absMin = clearTime(new Date(initDate[0], initDate[1], initDate[2])); me.absMax = dateUtil.add(clearTime(new Date(initDate[0], initDate[1], initDate[2])), 'mi', (24 * 60) - 1); me.updateList(); me.callParent(); }, applyStore: function(store, oldStore) { if (store === true) { store = Ext.picker.Time.createStore(this.format, this.increment); } return store; }, setMinValue: function(value) { this.minValue = value; this.updateList(); }, setMaxValue: function(value) { this.maxValue = value; this.updateList(); }, normalizeDate: function(date) { var initDate = this.initDate; date.setFullYear(initDate[0], initDate[1], initDate[2]); return date; }, updateList: function() { var me = this, min = me.normalizeDate(me.minValue || me.absMin), max = me.normalizeDate(me.maxValue || me.absMax), filters = me.getStore().getFilters(), filter = me.rangeFilter; filters.beginUpdate(); if (filter) { filters.remove(filter); } filter = me.rangeFilter = new Ext.util.Filter({ filterFn: function(record) { var date = record.get('date'); return date >= min && date <= max; } }); filters.add(filter); filters.endUpdate(); } }, function() { this.prototype.modelType = Ext.define(null, { extend: 'Ext.data.Model', fields: [ 'disp', 'date' ] }); }); Ext.define('Ext.form.field.Time', { extend: 'Ext.form.field.ComboBox', alias: 'widget.timefield', requires: [ 'Ext.form.field.Date', 'Ext.picker.Time', 'Ext.view.BoundListKeyNav', 'Ext.Date' ], alternateClassName: [ 'Ext.form.TimeField', 'Ext.form.Time' ], triggerCls: Ext.baseCSSPrefix + 'form-time-trigger', 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, pickerMaxHeight: 300, selectOnTab: true, snapToIncrement: false, valuePublishEvent: [ 'select', 'blur' ], initDate: '1/1/2008', initDateParts: [ 2008, 0, 1 ], initDateFormat: 'j/n/Y', queryMode: 'local', displayField: 'disp', valueField: 'date', initComponent: function() { var me = this, min = me.minValue, max = me.maxValue; if (min) { me.setMinValue(min); } if (max) { me.setMaxValue(max); } me.displayTpl = new Ext.XTemplate('' + '{[typeof values === "string" ? values : this.formatDate(values["' + me.displayField + '"])]}' + '' + me.delimiter + '' + '', { formatDate: me.formatDate.bind(me) }); me.store = Ext.picker.Time.createStore(me.format, me.increment); me.callParent(); me.getPicker(); }, isEqual: function(v1, v2) { var fromArray = Ext.Array.from, isEqual = Ext.Date.isEqual, i, len; v1 = fromArray(v1); v2 = fromArray(v2); len = v1.length; if (len !== v2.length) { return false; } for (i = 0; i < len; i++) { if (!isEqual(v2[i], v1[i])) { return false; } } return true; }, setMinValue: function(value) { var me = this, picker = me.picker; me.setLimit(value, true); if (picker) { picker.setMinValue(me.minValue); } }, setMaxValue: function(value) { var me = this, picker = me.picker; me.setLimit(value, false); if (picker) { picker.setMaxValue(me.maxValue); } }, setLimit: function(value, isMin) { var me = this, d, val; if (Ext.isString(value)) { d = me.parseDate(value); } else if (Ext.isDate(value)) { d = value; } if (d) { val = me.getInitDate(); val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()); } else { val = null; } me[isMin ? 'minValue' : 'maxValue'] = val; }, getInitDate: function(hours, minutes, seconds) { var parts = this.initDateParts; return new Date(parts[0], parts[1], parts[2], hours || 0, minutes || 0, seconds || 0, 0); }, valueToRaw: function(value) { return this.formatDate(this.parseDate(value)); }, getErrors: function(value) { value = arguments.length > 0 ? value : this.getRawValue(); var me = this, format = Ext.String.format, errors = me.callParent([ value ]), minValue = me.minValue, maxValue = me.maxValue, data = me.displayTplData, raw = me.getRawValue(), i, len, date, item; if (data && data.length > 0) { for (i = 0 , len = data.length; i < len; i++) { item = data[i]; item = item.date || item.disp; date = me.parseDate(item); if (!date) { errors.push(format(me.invalidText, item, Ext.Date.unescapeFormat(me.format))); continue; } if (minValue && date < minValue) { errors.push(format(me.minText, me.formatDate(minValue))); } if (maxValue && date > maxValue) { errors.push(format(me.maxText, me.formatDate(maxValue))); } } } else if (raw.length && !me.parseDate(raw)) { errors.push(format(me.invalidText, raw, Ext.Date.unescapeFormat(me.format))); } return errors; }, formatDate: function(items) { var formatted = [], i, len; items = Ext.Array.from(items); for (i = 0 , len = items.length; i < len; i++) { formatted.push(Ext.form.field.Date.prototype.formatDate.call(this, items[i])); } return formatted.join(this.delimiter); }, parseDate: function(value) { var me = this, val = value, altFormats = me.altFormats, altFormatsArray = me.altFormatsArray, i = 0, len; if (value && !Ext.isDate(value)) { val = me.safeParse(value, me.format); if (!val && altFormats) { altFormatsArray = altFormatsArray || altFormats.split('|'); len = altFormatsArray.length; for (; i < len && !val; ++i) { val = me.safeParse(value, altFormatsArray[i]); } } } if (val && me.snapToIncrement) { val = new Date(Ext.Number.snap(val.getTime(), me.increment * 60 * 1000)); } return val; }, safeParse: function(value, format) { var me = this, utilDate = Ext.Date, parsedDate, result = null; if (utilDate.formatContainsDateInfo(format)) { result = utilDate.parse(value, format); } else { parsedDate = utilDate.parse(me.initDate + ' ' + value, me.initDateFormat + ' ' + format); if (parsedDate) { result = parsedDate; } } return result; }, getSubmitValue: function() { var me = this, format = me.submitFormat || me.format, value = me.getValue(); return value ? Ext.Date.format(value, format) : null; }, createPicker: function() { var me = this; me.listConfig = Ext.apply({ xtype: 'timepicker', pickerField: me, cls: undefined, minValue: me.minValue, maxValue: me.maxValue, increment: me.increment, format: me.format, maxHeight: me.pickerMaxHeight }, me.listConfig); return me.callParent(); }, completeEdit: function() { var me = this, val = me.getValue(); me.callParent(arguments); if (me.validateValue(val)) { me.setValue(val); } }, findRecordByValue: function(value) { if (typeof value === 'string') { value = this.parseDate(value); } return this.callParent([ value ]); }, rawToValue: function(item) { var me = this, items, values, i, len; if (me.multiSelect) { values = []; items = Ext.Array.from(item); for (i = 0 , len = items.length; i < len; i++) { values.push(me.parseDate(items[i])); } return values; } return me.parseDate(item); }, setValue: function(v) { var me = this; if (me.creatingPicker) { return; } me.getPicker(); if (Ext.isDate(v)) { v = me.getInitDate(v.getHours(), v.getMinutes(), v.getSeconds()); } return me.callParent([ v ]); }, getValue: function() { return this.rawToValue(this.callParent(arguments)); } }); Ext.define('Ext.form.field.Trigger', { extend: 'Ext.form.field.Text', alias: [ 'widget.triggerfield', 'widget.trigger' ], requires: [ 'Ext.dom.Helper', 'Ext.util.ClickRepeater' ], alternateClassName: [ 'Ext.form.TriggerField', 'Ext.form.TwinTriggerField', 'Ext.form.Trigger' ], triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger', inheritableStatics: { warnDeprecated: function() { Ext.log.warn('Ext.form.field.Trigger is deprecated. Use Ext.form.field.Text instead.'); } }, onClassExtended: function() { this.warnDeprecated(); }, constructor: function(config) { this.self.warnDeprecated(); this.callParent([ config ]); } }); Ext.define('Ext.grid.CellEditor', { extend: 'Ext.Editor', alignment: 'l-l?', hideEl: false, cls: Ext.baseCSSPrefix + 'small-editor ' + Ext.baseCSSPrefix + 'grid-editor ' + Ext.baseCSSPrefix + 'grid-cell-editor', treeNodeSelector: '.' + Ext.baseCSSPrefix + 'tree-node-text', shim: false, shadow: false, constructor: function(config) { var field; this.y = 0; config = Ext.apply({}, config); field = config.field; if (field) { field.monitorTab = false; } this.callParent([ config ]); }, setGrid: function(grid) { var me = this, oldGrid = me.grid, view, viewListeners; if (grid !== oldGrid) { viewListeners = { beforerefresh: me.beforeViewRefresh, refresh: me.onViewRefresh, scope: me }; if (oldGrid) { oldGrid.getView().un(viewListeners); } view = grid.getView(); me.renderTo = view.getTargetEl().dom; me.grid = grid; view.on(viewListeners); } }, afterFirstLayout: function(width, height) { delete this.y; this.callParent([ width, height ]); }, beforeViewRefresh: function() { var me = this, dom = me.el && me.el.dom; if (dom) { if (me.editing && !(me.field.column && me.field.column.sorting)) { me.grid.view.cellFocused = false; me.wasAllowBlur = me.allowBlur; me.allowBlur = false; } if (dom.parentNode) { dom.parentNode.removeChild(dom); } } }, onViewRefresh: function() { var me = this, dom = me.el && me.el.dom, sorting; if (dom) { sorting = me.field.column && me.field.column.sorting; if (me.editing && !sorting) { me.allowBlur = me.wasAllowBlur; me.renderTo.appendChild(dom); me.grid.view.cellFocused = true; me.field.focus(); } else if (!sorting) { Ext.getDetachedBody().dom.appendChild(dom); } if (me.editing && sorting) { me.completeEdit(); } } }, startEdit: function(boundEl, value) { this.context = this.editingPlugin.context; this.callParent([ boundEl, value ]); }, onShow: function() { var me = this, innerCell = me.boundEl.first(); if (me.el.dom.parentNode !== me.renderTo) { me.renderTo.appendChild(me.el.dom); } if (innerCell) { if (me.isForTree) { innerCell = innerCell.child(me.treeNodeSelector); } innerCell.hide(); } me.callParent(arguments); }, onEditComplete: function(remainVisible) { if (remainVisible) { this.restoreCell(); } this.callParent(arguments); }, onHide: function() { this.restoreCell(); this.callParent(arguments); }, restoreCell: function() { var me = this, innerCell = me.boundEl.first(); if (innerCell) { if (me.isForTree) { innerCell = innerCell.child(me.treeNodeSelector); } innerCell.show(); } }, afterRender: function() { var me = this, field = me.field; me.callParent(arguments); if (field.isCheckbox) { field.mon(field.inputEl, { mousedown: me.onCheckBoxMouseDown, click: me.onCheckBoxClick, scope: me }); } }, onCheckBoxMouseDown: function() { this.completeEdit = Ext.emptyFn; }, onCheckBoxClick: function() { delete this.completeEdit; this.field.focus(false, 10); }, realign: function(autoSize) { var me = this, boundEl = me.boundEl, innerCell = boundEl.first(), innerCellTextNode = innerCell.dom.firstChild, width = boundEl.getWidth(), offsets = Ext.Array.clone(me.offsets), grid = me.grid, xOffset, v = '', isEmpty = !innerCellTextNode || (innerCellTextNode.nodeType === 3 && !(Ext.String.trim(v = innerCellTextNode.data).length)); if (me.isForTree) { xOffset = me.getTreeNodeOffset(innerCell); width -= Math.abs(xOffset); offsets[0] += xOffset; } if (grid.columnLines) { width -= boundEl.getBorderWidth('rl'); } if (autoSize === true) { me.field.setWidth(width); } if (isEmpty) { innerCell.dom.innerHTML = 'X'; } me.alignTo(innerCell, me.alignment, offsets); if (isEmpty) { innerCell.dom.firstChild.data = v; } }, getTreeNodeOffset: function(innerCell) { return innerCell.child(this.treeNodeSelector).getOffsetsTo(innerCell)[0]; }, onEditorTab: function(e) { var field = this.field; if (field.onEditorTab) { field.onEditorTab(e); } }, onFocusLeave: function(e) { this.previousFocus = null; this.callParent([ e ]); this.selectSameEditor = false; } }); Ext.define('Ext.grid.ColumnManager', { alternateClassName: [ 'Ext.grid.ColumnModel' ], columns: null, constructor: function(visibleOnly, headerCt, secondHeaderCt) { if (!headerCt.isRootHeader && !headerCt.isGroupHeader) { Ext.Error.raise('ColumnManager must be passed an instantiated HeaderContainer or group header'); } this.headerCt = headerCt; if (secondHeaderCt) { if (!headerCt.isRootHeader && !headerCt.isGroupHeader) { Ext.Error.raise('ColumnManager must be passed an instantiated HeaderContainer or group header'); } this.secondHeaderCt = secondHeaderCt; } this.visibleOnly = !!visibleOnly; }, getColumns: function() { if (!this.columns) { this.cacheColumns(); } return this.columns; }, hasVariableRowHeight: function() { var me = this, columns = me.getColumns(), len = columns.length, i; if (me.variableRowHeight == null) { me.variableRowHeight = false; for (i = 0; !me.variableRowHeight && i < len; i++) { me.variableRowHeight = !!columns[i].variableRowHeight; } } return me.variableRowHeight; }, getHeaderIndex: function(header) { if (header.isGroupHeader) { header = this.getHeaderColumns(header)[0]; } return Ext.Array.indexOf(this.getColumns(), header); }, getHeaderAtIndex: function(index) { var columns = this.getColumns(), col = columns[index]; return col || null; }, getPreviousSibling: function(header) { var index = this.getHeaderIndex(header), col = null; if (index > 0) { col = this.getColumns()[index - 1]; } return col; }, getNextSibling: function(header) { var index = this.getHeaderIndex(header), col; if (index !== -1) { col = this.getColumns()[index + 1]; } return col || null; }, getFirst: function() { var columns = this.getColumns(); return columns.length > 0 ? columns[0] : null; }, getLast: function() { var columns = this.getColumns(), len = columns.length; return len > 0 ? columns[len - 1] : null; }, getHeaderByDataIndex: function(dataIndex) { var columns = this.getColumns(), len = columns.length, i, header; for (i = 0; i < len; ++i) { header = columns[i]; if (header.dataIndex === dataIndex) { return header; } } return null; }, getHeaderById: function(id) { var columns = this.getColumns(), len = columns.length, i, header; for (i = 0; i < len; ++i) { header = columns[i]; if (header.getItemId() === id) { return header; } } return null; }, getVisibleHeaderClosestToIndex: function(index) { var result = this.getHeaderAtIndex(index); if (result && result.hidden) { result = result.next(':not([hidden])') || result.prev(':not([hidden])'); } return result; }, cacheColumns: function() { var columns = this.getHeaderColumns(this.headerCt), second = this.secondHeaderCt; if (second) { columns = columns.concat(this.getHeaderColumns(second)); } this.columns = columns; }, getHeaderColumns: function(header) { var result = this.visibleOnly ? header.getVisibleGridColumns() : header.getGridColumns(); return Ext.Array.clone(result); }, invalidate: function() { var root = this.rootColumns; this.columns = this.variableRowHeight = null; if (root) { root.invalidate(); } }, destroy: function() { this.columns = this.rootColumns = null; } }, function() { this.createAlias('indexOf', 'getHeaderIndex'); }); Ext.define('Ext.grid.RowEditorButtons', { extend: 'Ext.container.Container', alias: 'widget.roweditorbuttons', frame: true, shrinkWrap: true, position: 'bottom', constructor: function(config) { var me = this, rowEditor = config.rowEditor, cssPrefix = Ext.baseCSSPrefix, plugin = rowEditor.editingPlugin; config = Ext.apply({ baseCls: cssPrefix + 'grid-row-editor-buttons', defaults: { xtype: 'button', ui: rowEditor.buttonUI, scope: plugin, flex: 1, minWidth: Ext.panel.Panel.prototype.minButtonWidth }, items: [ { cls: cssPrefix + 'row-editor-update-button', itemId: 'update', handler: plugin.completeEdit, text: rowEditor.saveBtnText, disabled: rowEditor.updateButtonDisabled }, { cls: cssPrefix + 'row-editor-cancel-button', itemId: 'cancel', handler: plugin.cancelEdit, text: rowEditor.cancelBtnText } ] }, config); me.callParent([ config ]); me.addClsWithUI(me.position); }, setButtonPosition: function(position) { var me = this, rowEditor = this.rowEditor, rowEditorHeight = rowEditor.getHeight(), rowEditorBody = rowEditor.body, bottom = '', top = ''; me.removeClsWithUI(me.position); me.position = position; me.addClsWithUI(position); if (position === 'top') { bottom = (rowEditorHeight - rowEditorBody.getBorderWidth('t')) + 'px'; } else { top = (rowEditorHeight - rowEditorBody.getBorderWidth('b')) + 'px'; } me.el.setStyle({ top: top, bottom: bottom }); }, privates: { getFramingInfoCls: function() { return this.baseCls + '-' + this.ui + '-' + this.position; }, getFrameInfo: function() { var frameInfo = this.callParent(); frameInfo.top = true; return frameInfo; } } }); Ext.define('Ext.grid.RowEditor', { extend: 'Ext.form.Panel', alias: 'widget.roweditor', requires: [ 'Ext.tip.ToolTip', 'Ext.util.KeyNav', 'Ext.grid.RowEditorButtons' ], saveBtnText: 'Update', cancelBtnText: 'Cancel', errorsText: 'Errors', dirtyText: 'You need to commit or cancel your changes', lastScrollLeft: 0, lastScrollTop: 0, border: false, _wrapCls: Ext.baseCSSPrefix + 'grid-row-editor-wrap', errorCls: Ext.baseCSSPrefix + 'grid-row-editor-errors-item', buttonUI: 'default', hideMode: 'offsets', initComponent: function() { var me = this, grid = me.editingPlugin.grid, Container = Ext.container.Container, form, normalCt, lockedCt; me.cls = Ext.baseCSSPrefix + 'grid-editor ' + Ext.baseCSSPrefix + 'grid-row-editor'; me.layout = { type: 'hbox', align: 'middle' }; me.lockable = grid.lockable; if (me.lockable) { me.items = [ lockedCt = me.lockedColumnContainer = new Container({ id: grid.id + '-locked-editor-cells', scrollable: { x: false, y: false }, layout: { type: 'hbox', align: 'middle' }, margin: '0 1 0 0' }), normalCt = me.normalColumnContainer = new Container({ scrollable: { x: false, y: false }, flex: 1, id: grid.id + '-normal-editor-cells', layout: { type: 'hbox', align: 'middle' } }) ]; lockedCt.getScrollable().addPartner(grid.lockedGrid.view.getScrollable(), 'x'); normalCt.getScrollable().addPartner(grid.normalGrid.view.getScrollable(), 'x'); } else { me.setScrollable({ x: false, y: false }); me.getScrollable().addPartner(grid.view.getScrollable(), 'x'); me.lockedColumnContainer = me.normalColumnContainer = me; } me.callParent(); if (me.fields) { me.addFieldsForColumn(me.fields, true); me.insertColumnEditor(me.fields); delete me.fields; } me.mon(Ext.GlobalEvents, { scope: me, show: me.repositionIfVisible }); form = me.getForm(); form.trackResetOnLoad = true; form.on('validitychange', me.onValidityChange, me); form.on('errorchange', me.onErrorChange, me); }, onGridResize: function() { var me = this, clientWidth = me.getClientWidth(), grid = me.editingPlugin.grid, gridBody = grid.body, btns = me.getFloatingButtons(); me.wrapEl.setLocalX(gridBody.getOffsetsTo(grid)[0] + gridBody.getBorderWidth('l') - grid.el.getBorderWidth('l')); me.setWidth(clientWidth); btns.setLocalX((clientWidth - btns.getWidth()) / 2); if (me.lockable) { me.lockedColumnContainer.setWidth(grid.lockedGrid.view.el.dom.clientWidth); } }, syncAllFieldWidths: function() { var me = this, editors = me.query('[isEditorComponent]'), len = editors.length, column, i; for (i = 0; i < len; ++i) { column = editors[i].column; if (column.isVisible()) { me.onColumnShow(column); } } }, syncFieldWidth: function(column) { var field = column.getEditor(), width; field._marginWidth = (field._marginWidth || field.el.getMargin('lr')); width = column.getWidth() - field._marginWidth; field.setWidth(width); if (field.xtype === 'displayfield') { field.inputWidth = width; } }, onValidityChange: function(form, valid) { this.updateButton(valid); this.isValid = valid; }, onErrorChange: function() { var me = this, valid; if (me.errorSummary && me.isVisible()) { valid = me.getForm().isValid(); me[valid ? 'hideToolTip' : 'showToolTip'](); } }, updateButton: function(valid) { var buttons = this.floatingButtons; if (buttons) { buttons.child('#update').setDisabled(!valid); } else { this.updateButtonDisabled = !valid; } }, afterRender: function() { var me = this, plugin = me.editingPlugin, grid = plugin.grid, view = grid.lockable ? grid.normalGrid.view : grid.view; me.callParent(arguments); me.scrollingView = view; me.scrollingViewEl = view.el; view.on('scroll', me.onViewScroll, me); me.mon(me.el, { click: Ext.emptyFn, stopPropagation: true }); me.mon(grid, 'resize', me.onGridResize, me); if (me.lockable) { grid.lockedGrid.view.on('resize', 'onGridResize', me); } me.el.swallowEvent([ 'keypress', 'keydown' ]); me.initKeyNav(); me.mon(plugin.view, { beforerefresh: me.onBeforeViewRefresh, refresh: me.onViewRefresh, itemremove: me.onViewItemRemove, scope: me }); me.preventReposition = true; me.syncAllFieldWidths(); delete me.preventReposition; }, initKeyNav: function() { var me = this, plugin = me.editingPlugin; me.keyNav = new Ext.util.KeyNav(me.el, { enter: plugin.onEnterKey, esc: plugin.onEscKey, scope: plugin }); }, onBeforeViewRefresh: function(view) { var me = this, viewDom = view.el.dom; if (me.el.dom.parentNode === viewDom) { viewDom.removeChild(me.el.dom); } }, onViewRefresh: function(view) { var me = this, context = me.context, row; if (context && (row = view.getRow(context.record))) { context.row = row; me.reposition(); if (me.tooltip && me.tooltip.isVisible()) { me.tooltip.setTarget(context.row); } } else { me.editingPlugin.cancelEdit(); } }, onViewItemRemove: function(record, index, item, view) { if (!view.refreshing) { var context = this.context; if (context && record === context.record) { this.editingPlugin.cancelEdit(); } } }, onViewScroll: function() { var me = this, viewEl = me.editingPlugin.view.el, scrollingView = me.scrollingView, scrollTop = scrollingView.getScrollY(), scrollLeft = scrollingView.getScrollX(), scrollTopChanged = scrollTop !== me.lastScrollTop, row; me.lastScrollTop = scrollTop; me.lastScrollLeft = scrollLeft; if (me.isVisible()) { row = Ext.getDom(me.context.row); if (row && viewEl.contains(row)) { if (scrollTopChanged) { me.context.row = row; me.reposition(null, true); if ((me.tooltip && me.tooltip.isVisible()) || me.hiddenTip) { me.repositionTip(); } me.syncEditorClip(); } } else { me.setLocalY(-400); } } }, onColumnResize: function(column, width) { var me = this; if (me.rendered && !me.editingPlugin.reconfiguring) { me.onGridResize(); me.onViewScroll(); if (!column.isGroupHeader) { me.syncFieldWidth(column); me.repositionIfVisible(); } } }, onColumnHide: function(column) { if (!this.editingPlugin.reconfiguring && !column.isGroupHeader) { column.getEditor().hide(); this.repositionIfVisible(); } }, onColumnShow: function(column) { var me = this; if (me.rendered && !me.editingPlugin.reconfiguring && !column.isGroupHeader && column.getEditor) { column.getEditor().show(); me.syncFieldWidth(column); if (!me.preventReposition) { this.repositionIfVisible(); } } }, onColumnMove: function(column, fromIdx, toIdx) { var me = this, locked = column.isLocked(), fieldContainer = locked ? me.lockedColumnContainer : me.normalColumnContainer, columns, i, len, after, offset; if (column.isGroupHeader) { Ext.suspendLayouts(); after = toIdx > fromIdx; offset = after ? 1 : 0; columns = column.getGridColumns(); for (i = 0 , len = columns.length; i < len; ++i) { column = columns[i]; toIdx = column.getIndex(); if (after) { ++offset; } me.setColumnEditor(column, toIdx + offset, fieldContainer); } Ext.resumeLayouts(true); } else { me.setColumnEditor(column, column.getIndex(), fieldContainer); } }, setColumnEditor: function(column, idx, fieldContainer) { this.addFieldsForColumn(column); fieldContainer.insert(idx, column.getEditor()); }, onColumnAdd: function(column) { if (column.isGroupHeader) { column = column.getGridColumns(); } this.addFieldsForColumn(column); this.insertColumnEditor(column); this.preventReposition = false; }, insertColumnEditor: function(column) { var me = this, fieldContainer, len, i; if (Ext.isArray(column)) { for (i = 0 , len = column.length; i < len; i++) { me.insertColumnEditor(column[i]); } return; } if (!column.getEditor) { return; } fieldContainer = column.isLocked() ? me.lockedColumnContainer : me.normalColumnContainer; fieldContainer.insert(column.getIndex(), column.getEditor()); me.needsSyncFieldWidths = true; }, destroyColumnEditor: function(column) { var field; if (column.hasEditor() && (field = column.getEditor())) { field.destroy(); } }, getFloatingButtons: function() { var me = this, btns = me.floatingButtons; if (!btns) { me.floatingButtons = btns = new Ext.grid.RowEditorButtons({ rowEditor: me }); } return btns; }, repositionIfVisible: function(c) { var me = this, view = me.view; if (c && (c === me || !c.el.isAncestor(view.el))) { return; } if (me.isVisible() && view.isVisible(true)) { me.reposition(); } }, isLayoutChild: function(ownerCandidate) { return false; }, getRefOwner: function() { return this.editingPlugin.grid; }, getRefItems: function(deep) { var me = this, result; if (me.lockable) { result = [ me.lockedColumnContainer ]; result.push.apply(result, me.lockedColumnContainer.getRefItems(deep)); result.push(me.normalColumnContainer); result.push.apply(result, me.normalColumnContainer.getRefItems(deep)); } else { result = me.callParent(arguments); } result.push.apply(result, me.getFloatingButtons().getRefItems(deep)); return result; }, reposition: function(animateConfig, fromScrollHandler) { var me = this, context = me.context, row = context && context.row, yOffset = 0, wrapEl = me.wrapEl, rowTop, localY, deltaY, afterPosition; if (row && Ext.isElement(row)) { deltaY = me.syncButtonPosition(me.getScrollDelta()); if (!me.editingPlugin.grid.rowLines) { yOffset = -parseInt(Ext.fly(row).first().getStyle('border-bottom-width'), 10); } rowTop = me.calculateLocalRowTop(row); localY = me.calculateEditorTop(rowTop) + yOffset; if (!fromScrollHandler) { afterPosition = function() { if (deltaY) { me.scrollingViewEl.scrollBy(0, deltaY, true); } me.focusColumnField(context.column); }; } me.syncEditorClip(); if (animateConfig) { wrapEl.animate(Ext.applyIf({ to: { top: localY }, duration: animateConfig.duration || 125, callback: afterPosition }, animateConfig)); } else { wrapEl.setLocalY(localY); if (afterPosition) { afterPosition(); } } } }, getScrollDelta: function() { var me = this, scrollingViewDom = me.scrollingViewEl.dom, context = me.context, body = me.body, deltaY = 0; if (context) { deltaY = Ext.fly(context.row).getOffsetsTo(scrollingViewDom)[1]; if (deltaY < 0) { deltaY -= body.getBorderPadding().beforeY; } else if (deltaY > 0) { deltaY = Math.max(deltaY + me.getHeight() + me.floatingButtons.getHeight() - scrollingViewDom.clientHeight - body.getBorderWidth('b'), 0); if (deltaY > 0) { deltaY -= body.getBorderPadding().afterY; } } } return deltaY; }, calculateLocalRowTop: function(row) { var grid = this.editingPlugin.grid; return Ext.fly(row).getOffsetsTo(grid)[1] - grid.el.getBorderWidth('t') + this.lastScrollTop; }, calculateEditorTop: function(rowTop) { return rowTop - this.body.getBorderPadding().beforeY - this.lastScrollTop; }, getClientWidth: function() { var me = this, grid = me.editingPlugin.grid, result; if (me.lockable) { result = grid.lockedGrid.getWidth() + grid.normalGrid.view.el.dom.clientWidth; } else { result = grid.view.el.dom.clientWidth; } return result; }, getEditor: function(fieldInfo) { var me = this; if (Ext.isNumber(fieldInfo)) { return me.query('[isEditorComponent]')[fieldInfo]; } else if (fieldInfo.isHeader && !fieldInfo.isGroupHeader) { return fieldInfo.getEditor(); } }, addFieldsForColumn: function(column, initial) { var me = this, i, length, field; if (Ext.isArray(column)) { for (i = 0 , length = column.length; i < length; i++) { me.addFieldsForColumn(column[i], initial); } return; } if (column.getEditor) { field = column.getEditor(null, me.getDefaultFieldCfg()); if (column.align === 'right') { field.fieldStyle = 'text-align:right'; } if (column.xtype === 'actioncolumn') { field.fieldCls += ' ' + Ext.baseCSSPrefix + 'form-action-col-field'; } if (me.isVisible() && me.context) { if (field.is('displayfield')) { me.renderColumnData(field, me.context.record, column); } else { field.suspendEvents(); field.setValue(me.context.record.get(column.dataIndex)); field.resumeEvents(); } } if (column.hidden) { me.onColumnHide(column); } else if (column.rendered && !initial) { me.onColumnShow(column); } } }, getDefaultFieldCfg: function() { return { xtype: 'displayfield', getModelData: function() { return null; } }; }, loadRecord: function(record) { var me = this, form = me.getForm(), fields = form.getFields(), items = fields.items, length = items.length, i, displayFields, isValid, item; for (i = 0; i < length; i++) { item = items[i]; item.suspendEvents(); item.resetToInitialValue(); } form.loadRecord(record); for (i = 0; i < length; i++) { items[i].resumeEvents(); } if (form.hasInvalidField() === form.wasValid) { delete form.wasValid; } isValid = form.isValid(); if (me.errorSummary) { if (isValid) { me.hideToolTip(); } else { me.showToolTip(); } } me.updateButton(isValid); displayFields = me.query('>displayfield'); length = displayFields.length; for (i = 0; i < length; i++) { me.renderColumnData(displayFields[i], record); } }, renderColumnData: function(field, record, activeColumn) { var me = this, grid = me.editingPlugin.grid, headerCt = grid.headerCt, view = me.scrollingView, store = view.dataSource, column = activeColumn || field.column, value = record.get(column.dataIndex), renderer = column.editRenderer || column.renderer, metaData, rowIdx, colIdx, scope = (column.usingDefaultRenderer && !column.scope) ? column : column.scope; if (renderer) { metaData = { tdCls: '', style: '' }; rowIdx = store.indexOf(record); colIdx = headerCt.getHeaderIndex(column); value = renderer.call(scope || headerCt.ownerCt, value, metaData, record, rowIdx, colIdx, store, view); } field.setRawValue(value); }, beforeEdit: function() { var me = this, scrollDelta; if (me.isVisible() && me.errorSummary && !me.autoCancel && me.isDirty()) { scrollDelta = me.getScrollDelta(); if (scrollDelta) { me.scrollingViewEl.scrollBy(0, scrollDelta, true); } me.showToolTip(); return false; } }, startEdit: function(record, columnHeader) { var me = this, editingPlugin = me.editingPlugin, grid = editingPlugin.grid, context = me.context = editingPlugin.context, alreadyVisible = me.isVisible(), wrapEl = me.wrapEl; Ext.suspendLayouts(); if (!me.rendered) { me.width = me.getClientWidth(); me.render(grid.el, grid.el.dom.firstChild); wrapEl = me.wrapEl = me.el.wrap(); wrapEl.setVisibilityMode(3); wrapEl.addCls(me._wrapCls); me.getFloatingButtons().render(wrapEl); me.onViewScroll(); } context.grid.getSelectionModel().selectByPosition({ row: record, column: columnHeader }); me.onGridResize(); me.loadRecord(record); Ext.resumeLayouts(alreadyVisible); if (alreadyVisible) { me.reposition(true); } else { grid.ensureVisible(record); me.show(); } }, syncButtonPosition: function(scrollDelta) { var me = this, floatingButtons = me.getFloatingButtons(), scrollingView = me.scrollingView, overflow = me.getScrollDelta() - (scrollingView.getScrollable().getSize().y - scrollingView.getScrollY() - me.scrollingViewEl.dom.clientHeight); if (overflow > 0) { if (!me._buttonsOnTop) { floatingButtons.setButtonPosition('top'); me._buttonsOnTop = true; } scrollDelta = 0; } else if (me._buttonsOnTop !== false) { floatingButtons.setButtonPosition('bottom'); me._buttonsOnTop = false; } return scrollDelta; }, syncEditorClip: function() { var me = this, overflow = me.getScrollDelta(), el = me.el, floatingButtons = me.floatingButtons, btnEl = floatingButtons.el, max = Math.max, body, btnHeight, editorHeight; if (overflow) { me.isOverflowing = true; body = me.body; btnHeight = floatingButtons.getHeight(); editorHeight = me.getHeight(); max = Math.max; if (overflow > 0) { if (me._buttonsOnTop) { overflow -= (btnHeight - body.getBorderWidth('b')); me.clipBottom(el, max(editorHeight - overflow), 0); overflow -= (editorHeight - body.getBorderWidth('t')); if (overflow > 0) { me.clipBottom(btnEl, max(btnHeight - overflow, 0)); } else { me.clearClip(btnEl); } } else { me.clipBottom(btnEl, max(btnHeight - overflow, 0)); overflow -= (btnHeight - body.getBorderWidth('b')); if (overflow > 0) { me.clipBottom(el, max(editorHeight - overflow, 0)); } else { me.clearClip(el); } } } else if (overflow < 0) { overflow = Math.abs(overflow); me.clipTop(el, overflow); overflow -= (editorHeight - body.getBorderWidth('b')); if (overflow > 0) { me.clipTop(btnEl, overflow); } else { me.clearClip(btnEl); } } } else if (me.isOverflowing) { me.clearClip(btnEl); me.clearClip(el); me.isOverflowing = false; } }, focusColumnField: function(column) { var field, didFocus; if (column && !column.isDestroyed) { if (column.isVisible()) { field = this.getEditor(column); if (field && field.isFocusable(true)) { didFocus = true; field.focus(); } } if (!didFocus) { this.focusColumnField(column.next()); } } }, cancelEdit: function() { var me = this, form = me.getForm(), fields = form.getFields(), items = fields.items, length = items.length, i; me.hide(); form.clearInvalid(); for (i = 0; i < length; i++) { items[i].suspendEvents(); } form.reset(); for (i = 0; i < length; i++) { items[i].resumeEvents(); } }, completeEdit: function() { var me = this, form = me.getForm(); if (!form.isValid()) { return false; } form.updateRecord(me.context.record); me.hide(); return true; }, onShow: function() { var me = this; me.wrapEl.show(); me.previousFocus = Ext.Element.getActiveElement(); me.callParent(arguments); if (me.needsSyncFieldWidths) { me.suspendLayouts(); me.syncAllFieldWidths(); me.resumeLayouts(true); } delete me.needsSyncFieldWidths; me.reposition(); }, onHide: function() { var me = this; if (me.el.contains(Ext.Element.getActiveElement())) { if (me.context) { me.context.view.grid.focus(); me.context = null; } else { me.previousFocus.focus(); } } me.wrapEl.hide(); me.callParent(arguments); if (me.tooltip) { me.hideToolTip(); } }, onResize: function(width, height) { this.wrapEl.setSize(width, height); }, isDirty: function() { return this.getForm().isDirty(); }, getToolTip: function() { var me = this, tip = me.tooltip, grid = me.editingPlugin.grid; if (!tip) { me.tooltip = tip = new Ext.tip.ToolTip({ cls: Ext.baseCSSPrefix + 'grid-row-editor-errors', title: me.errorsText, autoHide: false, closable: true, closeAction: 'disable', anchor: 'left', anchorToTarget: true, constrainPosition: true, constrainTo: document.body }); grid.add(tip); me.mon(grid, { afterlayout: me.onGridLayout, scope: me }); } return tip; }, hideToolTip: function() { var me = this, tip = me.getToolTip(); if (tip.rendered) { tip.disable(); } me.hiddenTip = false; }, showToolTip: function() { var me = this, tip = me.getToolTip(); tip.update(me.getErrors()); me.repositionTip(); tip.enable(); }, onGridLayout: function() { if (this.tooltip && this.tooltip.isVisible()) { this.repositionTip(); } }, repositionTip: function() { var me = this, tip = me.getToolTip(), context = me.context, row = Ext.get(context.row), viewEl = me.scrollingViewEl, viewHeight = viewEl.dom.clientHeight, viewTop = viewEl.getY(), viewBottom = viewTop + viewHeight, rowHeight = row.getHeight(), rowTop = row.getY(), rowBottom = rowTop + rowHeight; if (rowBottom > viewTop && rowTop < viewBottom) { tip.anchorTarget = viewEl; tip.mouseOffset = [ 0, row.getOffsetsTo(viewEl)[1] ]; tip.show(); me.hiddenTip = false; } else { tip.hide(); me.hiddenTip = true; } }, getErrors: function() { var me = this, errors = [], fields = me.query('>[isFormField]'), length = fields.length, i, fieldErrors, field; for (i = 0; i < length; i++) { field = fields[i]; fieldErrors = field.getErrors(); if (fieldErrors.length) { errors.push(me.createErrorListItem(fieldErrors[0], field.column.text)); } } if (!errors.length && !me.autoCancel && me.isDirty()) { errors[0] = me.createErrorListItem(me.dirtyText); } return '
      ' + errors.join('') + '
    '; }, createErrorListItem: function(e, name) { e = name ? name + ': ' + e : e; return '
  • ' + e + '
  • '; }, beforeDestroy: function() { Ext.destroy(this.floatingButtons, this.tooltip); this.callParent(); }, clipBottom: function(el, value) { el.setStyle('clip', 'rect(0 auto ' + value + 'px 0)'); }, clipTop: function(el, value) { el.setStyle('clip', 'rect(' + value + 'px, auto, auto, 0)'); }, clearClip: function(el) { el.setStyle('clip', Ext.isIE8 ? 'rect(-1000px auto 1000px auto)' : 'auto'); } }); Ext.define('Ext.grid.Scroller', { constructor: Ext.deprecated() }); Ext.define('Ext.view.DropZone', { extend: 'Ext.dd.DropZone', indicatorCls: Ext.baseCSSPrefix + 'grid-drop-indicator', indicatorHtml: [ '', '' ].join(''), constructor: function(config) { var me = this; Ext.apply(me, config); if (!me.ddGroup) { me.ddGroup = 'view-dd-zone-' + me.view.id; } me.callParent([ me.view.el ]); }, fireViewEvent: function() { var me = this, result; me.lock(); result = me.view.fireEvent.apply(me.view, arguments); me.unlock(); return result; }, getTargetFromEvent: function(e) { var node = e.getTarget(this.view.getItemSelector()), mouseY, nodeList, testNode, i, len, box; if (!node) { mouseY = e.getY(); 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; } } } return node; }, getIndicator: function() { var me = this; if (!me.indicator) { me.indicator = new Ext.Component({ ariaRole: 'presentation', html: me.indicatorHtml, cls: me.indicatorCls, ownerCt: me.view, floating: true, shadow: false }); } return me.indicator; }, 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"; } return pos; }, containsRecordAtOffset: function(records, record, offset) { if (!record) { return false; } 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); }, positionIndicator: function(node, data, e) { var me = this, view = me.view, pos = me.getPosition(e, node), overRecord = view.getRecord(node), draggingRecords = data.records, 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(); } if (view.touchScroll === 2) { indicatorY += view.getScrollY(); } me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, indicatorY); me.overRecord = overRecord; me.currentPosition = pos; } } else { me.invalidateDrop(); } }, invalidateDrop: function() { if (this.valid) { this.valid = false; this.getIndicator().hide(); } }, onNodeOver: function(node, dragZone, e, data) { var me = this; if (!Ext.Array.contains(data.records, me.view.getRecord(node))) { me.positionIndicator(node, data, e); } return me.valid ? me.dropAllowed : me.dropNotAllowed; }, notifyOut: function(node, dragZone, e, data) { var me = this; me.callParent(arguments); me.overRecord = me.currentPosition = null; me.valid = false; if (me.indicator) { me.indicator.hide(); } }, onContainerOver: function(dd, e, data) { var me = this, view = me.view, count = view.dataSource.getCount(); if (count) { me.positionIndicator(view.all.last(), data, e); } else { me.overRecord = me.currentPosition = null; me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, 0); me.valid = true; } return me.dropAllowed; }, onContainerDrop: function(dd, e, data) { return this.onNodeDrop(dd, null, e, data); }, onNodeDrop: function(targetNode, dragZone, e, data) { var me = this, dropHandled = false, dropHandlers = { wait: false, processDrop: function() { me.invalidateDrop(); me.handleNodeDrop(data, me.overRecord, me.currentPosition); dropHandled = true; me.fireViewEvent('drop', targetNode, data, me.overRecord, me.currentPosition); }, cancelDrop: function() { me.invalidateDrop(); dropHandled = true; } }, performOperation = false; if (me.valid) { performOperation = me.fireViewEvent('beforedrop', targetNode, data, me.overRecord, me.currentPosition, dropHandlers); if (dropHandlers.wait) { return; } if (performOperation !== false) { if (!dropHandled) { dropHandlers.processDrop(); } } } return performOperation; }, destroy: function() { Ext.destroy(this.indicator); delete this.indicator; this.callParent(); } }); Ext.define('Ext.grid.ViewDropZone', { extend: 'Ext.view.DropZone', indicatorHtml: '', indicatorCls: Ext.baseCSSPrefix + 'grid-drop-indicator', handleNodeDrop: function(data, record, position) { var view = this.view, store = view.getStore(), index, records, i, len; if (data.copy) { records = data.records; data.records = []; for (i = 0 , len = records.length; i < len; i++) { data.records.push(records[i].copy()); } } else { data.view.store.remove(data.records, data.view === view); } if (record && position) { index = store.indexOf(record); if (position !== 'before') { index++; } store.insert(index, data.records); } else { store.add(data.records); } view.getSelectionModel().select(data.records); view.getNavigationModel().setPosition(data.records[0]); } }); Ext.define('Ext.grid.column.Action', { extend: 'Ext.grid.column.Column', alias: [ 'widget.actioncolumn' ], alternateClassName: 'Ext.grid.ActionColumn', stopSelection: true, actionIdRe: new RegExp(Ext.baseCSSPrefix + 'action-col-(\\d+)'), altText: '', menuText: 'Actions', sortable: false, innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-action-col', actionIconCls: Ext.baseCSSPrefix + 'action-col-icon', constructor: function(config) { var me = this, cfg = Ext.apply({}, config), items = cfg.items || me.items || [ me ], hasGetClass, i, len; me.origRenderer = cfg.renderer || me.renderer; me.origScope = cfg.scope || me.scope; me.renderer = me.scope = cfg.renderer = cfg.scope = null; cfg.items = null; me.callParent([ cfg ]); me.items = items; for (i = 0 , len = items.length; i < len; ++i) { if (items[i].getClass) { hasGetClass = true; break; } } if (me.origRenderer || hasGetClass) { me.hasCustomRenderer = true; } }, initComponent: function() { var me = this; me.callParent(); if (me.sortable && !me.dataIndex) { me.sortable = false; } }, defaultRenderer: function(v, cellValues, record, rowIdx, colIdx, store, view) { var me = this, prefix = Ext.baseCSSPrefix, scope = me.origScope || me, items = me.items, len = items.length, i = 0, item, ret, disabled, tooltip; ret = Ext.isFunction(me.origRenderer) ? me.origRenderer.apply(scope, arguments) || '' : ''; cellValues.tdCls += ' ' + Ext.baseCSSPrefix + 'action-col-cell'; for (; i < len; i++) { item = items[i]; disabled = item.disabled || (item.isDisabled ? item.isDisabled.call(item.scope || scope, view, rowIdx, colIdx, item, record) : false); tooltip = disabled ? null : (item.tooltip || (item.getTip ? item.getTip.apply(item.scope || scope, arguments) : null)); if (!item.hasActionConfiguration) { item.stopSelection = me.stopSelection; item.disable = Ext.Function.bind(me.disableAction, me, [ i ], 0); item.enable = Ext.Function.bind(me.enableAction, me, [ i ], 0); item.hasActionConfiguration = true; } ret += '' + (item.altText || me.altText) + ''; } return ret; }, updater: function(cell, value, record, view, dataSource) { var cellValues = {}; cell.firstChild.innerHTML = this.defaultRenderer(value, cellValues, record, null, null, dataSource, view); Ext.fly(cell).addCls(cellValues.tdCls); }, enableAction: function(index, silent) { var me = this; if (!index) { index = 0; } else if (!Ext.isNumber(index)) { index = Ext.Array.indexOf(me.items, index); } me.items[index].disabled = false; me.up('tablepanel').el.select('.' + Ext.baseCSSPrefix + 'action-col-' + index).removeCls(me.disabledCls); if (!silent) { me.fireEvent('enable', me); } }, disableAction: function(index, silent) { var me = this; if (!index) { index = 0; } else if (!Ext.isNumber(index)) { index = Ext.Array.indexOf(me.items, index); } me.items[index].disabled = true; me.up('tablepanel').el.select('.' + Ext.baseCSSPrefix + 'action-col-' + index).addCls(me.disabledCls); if (!silent) { me.fireEvent('disable', me); } }, beforeDestroy: function() { this.renderer = this.items = null; return this.callParent(arguments); }, processEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) { var me = this, target = e.getTarget(), key = type === 'keydown' && e.getKey(), match, item, disabled; if (key && !Ext.fly(target).findParent(view.getCellSelector())) { target = Ext.fly(cell).down('.' + Ext.baseCSSPrefix + 'action-col-icon', true); } if (target && (match = target.className.match(me.actionIdRe))) { item = me.items[parseInt(match[1], 10)]; disabled = item.disabled || (item.isDisabled ? item.isDisabled.call(item.scope || me.origScope || me, view, recordIndex, cellIndex, item, record) : false); if (item && !disabled) { if (type === 'mousedown') { if (item.stopSelection) { e.preventDefault(); } return false; } if (type === 'click' || (key === e.ENTER || key === e.SPACE)) { Ext.callback(item.handler || me.handler, item.scope || me.origScope, [ view, recordIndex, cellIndex, item, e, record, row ], undefined, me); if (item.stopSelection !== false) { return false; } } } } return me.callParent(arguments); }, cascade: function(fn, scope) { fn.call(scope || this, this); }, getRefItems: function() { return []; }, privates: { getFocusables: 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: ' ', defaultFilterType: 'boolean', producesHTML: false, defaultRenderer: function(value) { if (value === undefined) { return this.undefinedText; } if (!value || value === 'false') { return this.falseText; } return this.trueText; }, updater: function(cell, value) { cell.firstChild.innerHTML = Ext.grid.column.Boolean.prototype.defaultRenderer.call(this, value); } }); Ext.define('Ext.grid.column.Check', { extend: 'Ext.grid.column.Column', alternateClassName: [ 'Ext.ux.CheckColumn', 'Ext.grid.column.CheckColumn' ], alias: 'widget.checkcolumn', align: 'center', stopSelection: true, tdCls: Ext.baseCSSPrefix + 'grid-cell-checkcolumn', innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-checkcolumn', clickTargetName: 'el', defaultFilterType: 'boolean', constructor: function() { this.scope = this; this.callParent(arguments); }, processEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) { var me = this, key = type === 'keydown' && e.getKey(), mousedown = type === 'mousedown', disabled = me.disabled, ret = false, checked; if (!disabled && (mousedown || (key === e.ENTER || key === e.SPACE))) { checked = !me.isRecordChecked(record); if (me.fireEvent('beforecheckchange', me, recordIndex, checked) !== false) { me.setRecordCheck(record, checked, cell, row, e); me.fireEvent('checkchange', me, recordIndex, checked); if (mousedown) { e.stopEvent(); } if (!me.stopSelection) { view.selModel.selectByPosition({ row: recordIndex, column: cellIndex }); } } } else if (!disabled && type === 'click') { ret = false; } else { ret = me.callParent(arguments); } return ret; }, onEnable: function() { this.callParent(arguments); this._setDisabled(false); }, onDisable: function() { this._setDisabled(true); }, _setDisabled: function(disabled) { var me = this, cls = me.disabledCls, items; items = me.up('tablepanel').el.select(me.getCellSelector()); if (disabled) { items.addCls(cls); } else { items.removeCls(cls); } }, defaultRenderer: function(value, cellValues) { var cssPrefix = Ext.baseCSSPrefix, cls = cssPrefix + 'grid-checkcolumn'; if (this.disabled) { cellValues.tdCls += ' ' + this.disabledCls; } if (value) { cls += ' ' + cssPrefix + 'grid-checkcolumn-checked'; } return ''; }, isRecordChecked: function(record) { var prop = this.property; if (prop) { return record[prop]; } return record.get(this.dataIndex); }, setRecordCheck: function(record, checked, cell, row, e) { var me = this, prop = me.property; if (prop) { record[prop] = checked; me.updater(cell, checked); } else { record.set(me.dataIndex, checked); } }, updater: function(cell, value) { var cellValues = {}, tdCls; cell.firstChild.innerHTML = this.defaultRenderer(value, cellValues); tdCls = cellValues.tdCls; if (tdCls) { Ext.fly(cell).addCls(tdCls); } } }); Ext.define('Ext.grid.column.Date', { extend: 'Ext.grid.column.Column', alias: [ 'widget.datecolumn' ], requires: [ 'Ext.Date' ], alternateClassName: 'Ext.grid.DateColumn', isDateColumn: true, defaultFilterType: 'date', producesHTML: false, initComponent: function() { if (!this.format) { this.format = Ext.Date.defaultFormat; } this.callParent(arguments); }, defaultRenderer: function(value) { return Ext.util.Format.date(value, this.format); }, updater: function(cell, value) { cell.firstChild.innerHTML = Ext.grid.column.Date.prototype.defaultRenderer.call(this, value); } }); Ext.define('Ext.grid.column.Number', { extend: 'Ext.grid.column.Column', alias: [ 'widget.numbercolumn' ], requires: [ 'Ext.util.Format' ], alternateClassName: 'Ext.grid.NumberColumn', defaultFilterType: 'number', format: '0,000.00', producesHTML: false, defaultRenderer: function(value) { return Ext.util.Format.number(value, this.format); }, updater: function(cell, value) { cell.firstChild.innerHTML = Ext.grid.column.Number.prototype.defaultRenderer.call(this, value); } }); Ext.define('Ext.grid.column.RowNumberer', { extend: 'Ext.grid.column.Column', alternateClassName: 'Ext.grid.RowNumberer', alias: 'widget.rownumberer', text: " ", width: 23, sortable: false, draggable: false, autoLock: true, lockable: false, align: 'right', producesHTML: false, constructor: function(config) { var me = this; me.width = me.width; me.callParent(arguments); me.sortable = false; me.scope = me; }, resizable: false, hideable: false, menuDisabled: true, dataIndex: '', cls: Ext.baseCSSPrefix + 'row-numberer', tdCls: Ext.baseCSSPrefix + 'grid-cell-row-numberer ' + Ext.baseCSSPrefix + 'grid-cell-special', innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-row-numberer', rowspan: undefined, defaultRenderer: function(value, metaData, record, rowIdx, colIdx, dataSource, view) { var rowspan = this.rowspan, page = dataSource.currentPage, result = view.store.indexOf(record); if (metaData && rowspan) { metaData.tdAttr = 'rowspan="' + rowspan + '"'; } if (page > 1) { result += (page - 1) * dataSource.pageSize; } return result + 1; }, updater: function(cell, value, record, view, dataSource) { cell.firstChild.innerHTML = this.defaultRenderer(value, null, record, null, null, dataSource, view); } }); Ext.define('Ext.grid.column.Template', { extend: 'Ext.grid.column.Column', alias: [ 'widget.templatecolumn' ], requires: [ 'Ext.XTemplate' ], alternateClassName: 'Ext.grid.TemplateColumn', initComponent: function() { var me = this; me.tpl = (!Ext.isPrimitive(me.tpl) && me.tpl.compile) ? me.tpl : new Ext.XTemplate(me.tpl); me.hasCustomRenderer = true; me.callParent(arguments); }, defaultRenderer: function(value, meta, record) { var data = Ext.apply({}, record.data, record.getAssociatedData()); return this.tpl.apply(data); }, updater: function(cell, value) { cell.firstChild.innerHTML = Ext.grid.column.CheckColumn.prototype.defaultRenderer.call(this, value); } }); Ext.define('Ext.grid.column.Widget', { extend: 'Ext.grid.column.Column', alias: 'widget.widgetcolumn', config: { defaultWidgetUI: {} }, sortable: false, onWidgetAttach: null, stopSelection: true, preventUpdate: true, initComponent: function() { var me = this, widget; me.callParent(arguments); widget = me.widget; if (!widget || widget.isComponent) { Ext.Error.raise('column.Widget requires a widget configuration.'); } me.widget = widget = Ext.apply({}, widget); if (!widget.ui) { widget.ui = me.getDefaultWidgetUI()[widget.xtype] || 'default'; } me.isFixedSize = Ext.isNumber(widget.width); }, processEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) { var selector = view.innerSelector, target; if (this.stopSelection && type === 'click') { target = e.getTarget(selector); if (target && target !== e.target) { return false; } } }, beforeRender: function() { var me = this, tdCls = me.tdCls, widget; me.listenerScopeFn = function(defaultScope) { if (defaultScope === 'this') { return this; } return me.resolveListenerScope(defaultScope); }; me.liveWidgets = {}; me.cachedStyles = {}; me.freeWidgetStack = [ widget = me.getFreeWidget() ]; tdCls = tdCls ? tdCls + ' ' : ''; me.tdCls = tdCls + widget.getTdCls(); me.setupViewListeners(me.getView()); me.callParent(); }, afterRender: function() { var view = this.getView(); this.callParent(); if (view && view.viewReady && !view.ownerGrid.reconfiguring) { this.onViewRefresh(view, view.getViewRange()); } }, defaultRenderer: Ext.emptyFn, updater: function(cell, value, record) { this.updateWidget(record); }, onResize: function(newWidth) { var me = this, liveWidgets = me.liveWidgets, view = me.getView(), id, cell; if (!me.isFixedSize && me.rendered && view && view.viewReady) { cell = view.getEl().down(me.getCellInnerSelector()); if (cell) { newWidth -= parseInt(me.getCachedStyle(cell, 'padding-left'), 10) + parseInt(me.getCachedStyle(cell, 'padding-right'), 10); for (id in liveWidgets) { liveWidgets[id].setWidth(newWidth); } } } }, onAdded: function() { var me = this, view; me.callParent(arguments); view = me.getView(); if (view) { me.setupViewListeners(view); if (view && view.viewReady && me.rendered && view.getEl().down(me.getCellSelector())) { me.onViewRefresh(view, view.getViewRange()); } } }, onRemoved: function(isDestroying) { var me = this, liveWidgets = me.liveWidgets, viewListeners = me.viewListeners, id; if (me.rendered) { me.viewListeners = viewListeners && Ext.destroy(viewListeners); if (!isDestroying) { for (id in liveWidgets) { liveWidgets[id].detachFromBody(); } } } me.callParent(arguments); }, onDestroy: function() { var me = this, oldWidgetMap = me.liveWidgets, freeWidgetStack = me.freeWidgetStack, id, widget, i, len; if (me.rendered) { for (id in oldWidgetMap) { widget = oldWidgetMap[id]; widget.$widgetRecord = widget.$widgetColumn = null; delete widget.getWidgetRecord; delete widget.getWidgetColumn; widget.destroy(); } for (i = 0 , len = freeWidgetStack.length; i < len; ++i) { freeWidgetStack[i].destroy(); } } me.freeWidgetStack = me.liveWidgets = null; me.callParent(); }, getWidget: function(record) { var liveWidgets = this.liveWidgets, widget; if (record && liveWidgets) { widget = liveWidgets[record.internalId]; } return widget || null; }, privates: { getCachedStyle: function(el, style) { var cachedStyles = this.cachedStyles; return cachedStyles[style] || (cachedStyles[style] = Ext.fly(el).getStyle(style)); }, getFreeWidget: function() { var me = this, result = me.freeWidgetStack ? me.freeWidgetStack.pop() : null; if (!result) { result = Ext.widget(me.widget); result.resolveListenerScope = me.listenerScopeFn; result.getWidgetRecord = me.widgetRecordDecorator; result.getWidgetColumn = me.widgetColumnDecorator; result.dataIndex = me.dataIndex; result.measurer = me; result.ownerCmp = me; result.isLayoutChild = me.returnFalse; } return result; }, onBeforeRefresh: function() { var liveWidgets = this.liveWidgets, id; for (id in liveWidgets) { liveWidgets[id].detachFromBody(); } }, onItemAdd: function(records, index, items) { var me = this, view = me.getView(), hasAttach = !!me.onWidgetAttach, dataIndex = me.dataIndex, isFixedSize = me.isFixedSize, len = records.length, i, record, row, cell, widget, el, width; if (me.isVisible(true)) { for (i = 0; i < len; i++) { record = records[i]; if (record.isNonData) { continue; } row = view.getRowFromItem(items[i]); if (row) { cell = row.cells[me.getVisibleIndex()].firstChild; if (!isFixedSize && !width) { width = me.lastBox.width - parseInt(me.getCachedStyle(cell, 'padding-left'), 10) - parseInt(me.getCachedStyle(cell, 'padding-right'), 10); } widget = me.liveWidgets[record.internalId] = me.getFreeWidget(); widget.$widgetColumn = me; widget.$widgetRecord = record; Ext.fly(cell).empty(); if (widget.defaultBindProperty && dataIndex) { widget.setConfig(widget.defaultBindProperty, record.get(dataIndex)); } if (hasAttach) { Ext.callback(me.onWidgetAttach, me.scope, [ me, widget, record ], 0, me); } el = widget.el || widget.element; if (el) { cell.appendChild(el.dom); if (!isFixedSize) { widget.setWidth(width); } widget.reattachToBody(); } else { if (!isFixedSize) { widget.width = width; } widget.render(cell); } } } } }, onItemRemove: function(records, index, items) { var me = this, liveWidgets = me.liveWidgets, widget, item, id, len, i; if (me.rendered) { items = Ext.Array.from(items); len = items.length; for (i = 0; i < len; i++) { item = items[i]; id = item.getAttribute('data-recordId'); if (id && (widget = liveWidgets[id])) { delete liveWidgets[id]; me.freeWidgetStack.unshift(widget); widget.$widgetRecord = widget.$widgetColumn = null; widget.detachFromBody(); } } } }, onItemUpdate: function(record, recordIndex, oldItemDom) { this.updateWidget(record); }, onViewRefresh: function(view, records) { var me = this, rows = view.all, hasAttach = !!me.onWidgetAttach, oldWidgetMap = me.liveWidgets, dataIndex = me.dataIndex, isFixedSize = me.isFixedSize, cell, widget, el, width, recordId, itemIndex, recordIndex, record, id, lastBox, dom; if (me.isVisible(true)) { me.liveWidgets = {}; Ext.suspendLayouts(); for (itemIndex = rows.startIndex , recordIndex = 0; itemIndex <= rows.endIndex; itemIndex++ , recordIndex++) { record = records[recordIndex]; if (record.isNonData) { continue; } recordId = record.internalId; cell = view.getRow(rows.item(itemIndex)).cells[me.getVisibleIndex()].firstChild; widget = me.liveWidgets[recordId] = oldWidgetMap[recordId] || me.getFreeWidget(); widget.$widgetRecord = record; widget.$widgetColumn = me; delete oldWidgetMap[recordId]; lastBox = me.lastBox; if (lastBox && !isFixedSize && width === undefined) { width = lastBox.width - parseInt(me.getCachedStyle(cell, 'padding-left'), 10) - parseInt(me.getCachedStyle(cell, 'padding-right'), 10); } if (widget.defaultBindProperty && dataIndex) { widget.setConfig(widget.defaultBindProperty, records[recordIndex].get(dataIndex)); } if (hasAttach) { Ext.callback(me.onWidgetAttach, me.scope, [ me, widget, record ], 0, me); } el = widget.el || widget.element; if (el) { dom = el.dom; if (dom.parentNode !== cell) { Ext.fly(cell).empty(); cell.appendChild(el.dom); } if (!isFixedSize) { widget.setWidth(width); } widget.reattachToBody(); } else { if (!isFixedSize) { widget.width = width; } Ext.fly(cell).empty(); widget.render(cell); } } Ext.resumeLayouts(true); for (id in oldWidgetMap) { widget = oldWidgetMap[id]; widget.$widgetRecord = widget.$widgetColumn = null; me.freeWidgetStack.unshift(widget); widget.detachFromBody(); } } }, returnFalse: function() { return false; }, setupViewListeners: function(view) { var me = this; me.viewListeners = view.on({ refresh: me.onViewRefresh, itemupdate: me.onItemUpdate, itemadd: me.onItemAdd, itemremove: me.onItemRemove, scope: me, destroyable: true }); if (Ext.isIE8) { view.on('beforerefresh', me.onBeforeRefresh, me); } }, updateWidget: function(record) { var dataIndex = this.dataIndex, widget; if (this.rendered) { widget = this.liveWidgets[record.internalId]; if (widget && widget.defaultBindProperty && dataIndex) { widget.setConfig(widget.defaultBindProperty, record.get(dataIndex)); } } }, widgetRecordDecorator: function() { return this.$widgetRecord; }, widgetColumnDecorator: function() { return this.$widgetColumn; } } }); Ext.define('Ext.grid.feature.Feature', { extend: 'Ext.util.Observable', alias: 'feature.feature', wrapsItem: false, isFeature: true, disabled: false, hasFeatureEvent: true, eventPrefix: null, eventSelector: null, view: null, grid: null, constructor: function(config) { this.initialConfig = config; this.callParent(arguments); }, clone: function() { return new this.self(this.initialConfig); }, init: Ext.emptyFn, destroy: function() { this.clearListeners(); }, getFireEventArgs: function(eventName, view, featureTarget, e) { return [ eventName, view, featureTarget, e ]; }, vetoEvent: Ext.emptyFn, enable: function() { this.disabled = false; }, disable: function() { this.disabled = true; } }); Ext.define('Ext.grid.feature.AbstractSummary', { extend: 'Ext.grid.feature.Feature', alias: 'feature.abstractsummary', summaryRowCls: Ext.baseCSSPrefix + 'grid-row-summary', summaryRowSelector: '.' + Ext.baseCSSPrefix + 'grid-row-summary', readDataOptions: { recordCreator: Ext.identityFn }, summaryRowTpl: { fn: function(out, values, parent) { if (values.record.isSummary && this.summaryFeature.showSummaryRow) { this.summaryFeature.outputSummaryRecord(values.record, values, out, parent); } else { this.nextTpl.applyOut(values, out, parent); } }, priority: 1000 }, showSummaryRow: true, init: function() { var me = this; me.view.summaryFeature = me; me.rowTpl = me.view.self.prototype.rowTpl; me.view.addRowTpl(me.summaryRowTpl).summaryFeature = me; me.summaryData = {}; me.groupInfo = {}; if (!me.summaryTableCls) { me.summaryTableCls = Ext.baseCSSPrefix + 'grid-item'; } }, toggleSummaryRow: function(visible, fromLockingPartner) { var me = this, prev = me.showSummaryRow, doRefresh; visible = visible != null ? !!visible : !me.showSummaryRow; me.showSummaryRow = visible; if (visible && visible !== prev) { me.updateNext = true; } if (me.lockingPartner) { if (!fromLockingPartner) { me.lockingPartner.toggleSummaryRow(visible, true); doRefresh = true; } } else { doRefresh = true; } if (doRefresh) { me.grid.ownerGrid.getView().refresh(); } }, createRenderer: function(column, record) { var me = this, ownerGroup = record.ownerGroup, summaryData = ownerGroup ? me.summaryData[ownerGroup] : me.summaryData, dataIndex = column.dataIndex || column.getItemId(); return function(value, metaData) { return column.summaryRenderer ? column.summaryRenderer(record.data[dataIndex], summaryData, dataIndex, metaData) : record.data[dataIndex]; }; }, outputSummaryRecord: function(summaryRecord, contextValues, out) { var view = contextValues.view, savedRowValues = view.rowValues, columns = contextValues.columns || view.headerCt.getVisibleGridColumns(), colCount = columns.length, i, column, values = { view: view, record: summaryRecord, rowStyle: '', rowClasses: [ this.summaryRowCls ], itemClasses: [], recordIndex: -1, rowId: view.getRowId(summaryRecord), columns: columns }; for (i = 0; i < colCount; i++) { column = columns[i]; column.savedRenderer = column.renderer; if (column.summaryType || column.summaryRenderer) { column.renderer = this.createRenderer(column, summaryRecord); } else { column.renderer = Ext.emptyFn; } } view.rowValues = values; view.self.prototype.rowTpl.applyOut(values, out, parent); view.rowValues = savedRowValues; for (i = 0; i < colCount; i++) { column = columns[i]; column.renderer = column.savedRenderer; column.savedRenderer = null; } }, getSummary: function(store, type, field, group) { var isGrouped = !!group, item = isGrouped ? group : store; if (type) { if (Ext.isFunction(type)) { if (isGrouped) { return item.aggregate(field, type); } else { return item.aggregate(type, null, false, [ field ]); } } switch (type) { case 'count': return item.count(field); case 'min': return item.min(field); case 'max': return item.max(field); case 'sum': return item.sum(field); case 'average': return item.average(field); default: return ''; } } }, generateSummaryData: function(groupField) { var me = this, reader = me.view.store.getProxy().getReader(), convertedSummaryRow = {}, remoteData = {}, i, len, root, summaryRows; root = reader.getRootProperty(); reader.setRootProperty(me.remoteRoot); reader.buildExtractors(true); summaryRows = reader.getRoot(reader.rawData); if (summaryRows) { if (!Ext.isArray(summaryRows)) { summaryRows = [ summaryRows ]; } len = summaryRows.length; for (i = 0; i < len; ++i) { convertedSummaryRow = reader.extractRecordData(summaryRows[i], me.readDataOptions); if (groupField) { remoteData[convertedSummaryRow[groupField]] = convertedSummaryRow; } } } reader.setRootProperty(root); reader.buildExtractors(true); return groupField ? remoteData : convertedSummaryRow; }, setSummaryData: function(record, colId, summaryValue, groupName) { var summaryData = this.summaryData; if (groupName) { if (!summaryData[groupName]) { summaryData[groupName] = {}; } summaryData[groupName][colId] = summaryValue; } else { summaryData[colId] = summaryValue; } } }); Ext.define('Ext.grid.feature.GroupStore', { extend: 'Ext.util.Observable', isStore: true, defaultViewSize: 100, isFeatureStore: true, badGrouperKey: '[object Object]', constructor: function(groupingFeature, store) { var me = this; me.callParent(); me.groupingFeature = groupingFeature; me.bindStore(store); }, bindStore: function(store) { var me = this; if (!store || me.store !== store) { Ext.destroy(me.storeListeners); me.store = null; } if (store) { me.storeListeners = store.on({ groupchange: me.onGroupChange, remove: me.onRemove, add: me.onAdd, idchanged: me.onIdChanged, update: me.onUpdate, refresh: me.onRefresh, clear: me.onClear, scope: me, destroyable: true }); me.store = store; me.processStore(store); } }, processStore: function(store) { var me = this, groupingFeature = me.groupingFeature, collapseAll = groupingFeature.startCollapsed, data = me.data, ExtArray = Ext.Array, indexOf = ExtArray.indexOf, splice = ExtArray.splice, groups = store.getGroups(), groupCount = groups ? groups.length : 0, groupField = store.getGroupField(), groupNames = groups && ExtArray.unique(Ext.Object.getValues(groups.itemGroupKeys)), isCollapsed = false, oldMetaGroupCache = groupingFeature.getCache(), metaGroup, metaGroupCache, i, len, featureGrouper, group, groupName, groupPlaceholder, key, modelData, Model; groupingFeature.invalidateCache(); metaGroupCache = groupingFeature.getCache(); if (data) { data.clear(); } else { data = me.data = new Ext.util.Collection({ rootProperty: 'data', extraKeys: { byInternalId: { property: 'internalId', rootProperty: '' } } }); } if (store.getCount()) { groupingFeature.startCollapsed = false; if (groupCount > 0) { Model = store.getModel(); for (i = 0; i < groupCount; i++) { group = groups.getAt(i); key = group.getGroupKey(); if (me.badGrouperKey === key && (featureGrouper = groupingFeature.getGrouper(groupField))) { groupingFeature.startCollapsed = collapseAll; store.group(featureGrouper); return; } metaGroup = metaGroupCache[key] = oldMetaGroupCache[key] || groupingFeature.getMetaGroup(key); metaGroup.raw = group.getAt(0).get(groupField); splice(groupNames, indexOf(groupNames, key), 1); isCollapsed = metaGroup.isCollapsed = collapseAll || metaGroup.isCollapsed; if (isCollapsed) { modelData = {}; modelData[groupField] = key; metaGroup.placeholder = groupPlaceholder = new Model(modelData); groupPlaceholder.isNonData = groupPlaceholder.isCollapsedPlaceholder = true; groupPlaceholder.group = group; data.add(groupPlaceholder); } else { data.insert(me.data.length, group.items); } } if (groupNames.length) { for (i = 0 , len = groupNames.length; i < len; i++) { groupName = groupNames[i]; metaGroupCache[groupName] = oldMetaGroupCache[groupName]; } } oldMetaGroupCache = null; } else { data.add(store.getRange()); } } }, isCollapsed: function(name) { return this.groupingFeature.getCache()[name].isCollapsed; }, isLoading: function() { return false; }, getData: function() { return this.data; }, getCount: function() { return this.data.getCount(); }, getTotalCount: function() { return this.data.getCount(); }, rangeCached: function(start, end) { return end < this.getCount(); }, getRange: function(start, end, options) { var result = this.data.getRange(start, Ext.isNumber(end) ? end + 1 : end); if (options && options.callback) { options.callback.call(options.scope || this, result, start, end, options); } return result; }, getAt: function(index) { return this.data.getAt(index); }, getById: function(id) { return this.store.getById(id); }, getByInternalId: function(internalId) { return this.store.getByInternalId(internalId) || this.data.byInternalId.get(internalId); }, expandGroup: function(group) { var me = this, groupingFeature = me.groupingFeature, metaGroup, placeholder, startIdx, items; if (typeof group === 'string') { group = groupingFeature.getGroup(group); } if (group) { items = group.items; metaGroup = groupingFeature.getMetaGroup(group); placeholder = metaGroup.placeholder; } if (items.length && (startIdx = me.data.indexOf(placeholder)) !== -1) { metaGroup.isCollapsed = false; me.isExpandingOrCollapsing = 1; me.data.removeAt(startIdx); me.data.insert(startIdx, group.items); me.fireEvent('replace', me, startIdx, [ placeholder ], group.items); me.fireEvent('groupexpand', me, group); me.isExpandingOrCollapsing = 0; } }, collapseGroup: function(group) { var me = this, groupingFeature = me.groupingFeature, startIdx, placeholder, len, items; if (typeof group === 'string') { group = groupingFeature.getGroup(group); } if (group) { items = group.items; } if (items && (len = items.length) && (startIdx = me.data.indexOf(items[0])) !== -1) { groupingFeature.getMetaGroup(group).isCollapsed = true; me.isExpandingOrCollapsing = 2; me.data.removeAt(startIdx, len); me.data.insert(startIdx, placeholder = me.getGroupPlaceholder(group)); me.fireEvent('replace', me, startIdx, items, [ placeholder ]); me.fireEvent('groupcollapse', me, group); me.isExpandingOrCollapsing = 0; } }, getGroupPlaceholder: function(group) { var metaGroup = this.groupingFeature.getMetaGroup(group); if (!metaGroup.placeholder) { var store = this.store, Model = store.getModel(), modelData = {}, key = group.getGroupKey(), groupPlaceholder; modelData[store.getGroupField()] = key; groupPlaceholder = metaGroup.placeholder = new Model(modelData); groupPlaceholder.isNonData = groupPlaceholder.isCollapsedPlaceholder = true; groupPlaceholder.group = group; } return metaGroup.placeholder; }, indexOf: function(record) { if (!record.isCollapsedPlaceholder) { return this.data.indexOf(record); } return -1; }, indexOfId: function(id) { return this.data.indexOfKey(id); }, indexOfTotal: function(record) { return this.store.indexOf(record); }, onRefresh: function(store) { this.processStore(this.store); this.fireEvent('refresh', this); }, onRemove: function(store, records, index, isMove) { var me = this; if (store.isMoving()) { return; } me.processStore(me.store); me.fireEvent('refresh', me); }, onClear: function(store, records, startIndex) { var me = this; me.processStore(me.store); me.fireEvent('clear', me); }, onAdd: function(store, records, startIndex) { var me = this; me.processStore(me.store); me.fireEvent('replace', me, me.indexOf(records[0]), [], records); }, onIdChanged: function(store, rec, oldId, newId) { this.data.updateKey(rec, oldId); }, onUpdate: function(store, record, operation, modifiedFieldNames) { var me = this, groupingFeature = me.groupingFeature, group, metaGroup, firstRec, lastRec, items; if (store.isGrouped()) { group = record.group = groupingFeature.getGroup(record); metaGroup = groupingFeature.getMetaGroup(record); if (modifiedFieldNames && Ext.Array.contains(modifiedFieldNames, groupingFeature.getGroupField())) { return me.onRefresh(me.store); } if (metaGroup.isCollapsed) { me.fireEvent('update', me, metaGroup.placeholder); } else { Ext.suspendLayouts(); me.fireEvent('update', me, record, operation, modifiedFieldNames); items = group.items; firstRec = items[0]; lastRec = items[items.length - 1]; if (firstRec !== record) { firstRec.group = group; me.fireEvent('update', me, firstRec, 'edit', modifiedFieldNames); delete firstRec.group; } if (lastRec !== record && lastRec !== firstRec && groupingFeature.showSummaryRow) { lastRec.group = group; me.fireEvent('update', me, lastRec, 'edit', modifiedFieldNames); delete lastRec.group; } Ext.resumeLayouts(true); } delete record.group; } else { me.fireEvent('update', me, record, operation, modifiedFieldNames); } }, onGroupChange: function(store, grouper) { if (!grouper) { this.processStore(store); } this.fireEvent('groupchange', store, grouper); }, destroy: function() { var me = this; me.bindStore(null); me.clearListeners(); Ext.destroyMembers(me, 'data', 'groupingFeature'); } }); Ext.define('Ext.grid.feature.Grouping', { extend: 'Ext.grid.feature.Feature', mixins: { summary: 'Ext.grid.feature.AbstractSummary' }, requires: [ 'Ext.grid.feature.GroupStore' ], alias: 'feature.grouping', eventPrefix: 'group', eventSelector: '.' + Ext.baseCSSPrefix + 'grid-group-hd', refreshData: {}, wrapsItem: true, groupHeaderTpl: '{columnName}: {name}', depthToIndent: 17, collapsedCls: Ext.baseCSSPrefix + 'grid-group-collapsed', hdCollapsedCls: Ext.baseCSSPrefix + 'grid-group-hd-collapsed', hdNotCollapsibleCls: Ext.baseCSSPrefix + 'grid-group-hd-not-collapsible', collapsibleCls: Ext.baseCSSPrefix + 'grid-group-hd-collapsible', ctCls: Ext.baseCSSPrefix + 'group-hd-container', groupByText: 'Group by this field', showGroupsText: 'Show in groups', hideGroupedHeader: false, startCollapsed: false, enableGroupingMenu: true, enableNoGroups: true, collapsible: true, groupers: null, expandTip: 'Click to expand. CTRL key collapses all others', collapseTip: 'Click to collapse. CTRL/click collapses all others', showSummaryRow: false, outerTpl: [ '{%', 'if (!(this.groupingFeature.disabled || values.rows.length === 1 && values.rows[0].isSummary)) {', 'this.groupingFeature.setup(values.rows, values.view.rowValues);', '}', 'this.nextTpl.applyOut(values, out, parent);', 'if (!(this.groupingFeature.disabled || values.rows.length === 1 && values.rows[0].isSummary)) {', 'this.groupingFeature.cleanup(values.rows, values.view.rowValues);', '}', '%}', { priority: 200 } ], groupRowTpl: [ '{%', 'var me = this.groupingFeature,', 'colspan = "colspan=" + values.columns.length;', 'if (me.disabled || parent.rows.length === 1 && parent.rows[0].isSummary) {', 'values.needsWrap = false;', '} else {', 'me.setupRowData(values.record, values.rowIndex, values);', '}', '%}', '', '', '{% values.view.renderColumnSizer(values, out); %}', '', '', '{%', 'var groupTitleStyle = (!values.view.lockingPartner || (values.view.ownerCt === values.view.ownerCt.ownerLockable.lockedGrid) || (values.view.lockingPartner.headerCt.getVisibleGridColumns().length === 0)) ? "" : "visibility:hidden";', '%}', '
    ', '
    ', '{[values.groupHeaderTpl.apply(values.metaGroupCache, parent) || " "]}', '
    ', '
    ', '', '', '
    ', '', '{%', 'values.itemClasses.length = 0;', 'this.nextTpl.applyOut(values, out, parent);', '%}', '', '', '{%me.outputSummaryRecord(values.summaryRecord, values, out, parent);%}', '', '', '{%this.nextTpl.applyOut(values, out, parent);%}', '', { priority: 200, beginRowSync: function(rowSync) { var owner = this.owner; rowSync.add('header', owner.eventSelector); rowSync.add('summary', owner.summaryRowSelector); }, syncContent: function(destRow, sourceRow, columnsToUpdate) { destRow = Ext.fly(destRow, 'syncDest'); sourceRow = Ext.fly(sourceRow, 'sycSrc'); var owner = this.owner, destHd = destRow.down(owner.eventSelector, true), sourceHd = sourceRow.down(owner.eventSelector, true), destSummaryRow = destRow.down(owner.summaryRowSelector, true), sourceSummaryRow = sourceRow.down(owner.summaryRowSelector, true); if (destHd && sourceHd) { Ext.fly(destHd).syncContent(sourceHd); } if (destSummaryRow && sourceSummaryRow) { if (columnsToUpdate) { this.groupingFeature.view.updateColumns(destSummaryRow, sourceSummaryRow, columnsToUpdate); } else { Ext.fly(destSummaryRow).syncContent(sourceSummaryRow); } } } } ], init: function(grid) { var me = this, view = me.view, store = me.getGridStore(), lockPartner, dataSource; view.isGrouping = store.isGrouped(); me.mixins.summary.init.call(me); me.callParent([ grid ]); view.headerCt.on({ columnhide: me.onColumnHideShow, columnshow: me.onColumnHideShow, columnmove: me.onColumnMove, scope: me }); view.addTpl(Ext.XTemplate.getTpl(me, 'outerTpl')).groupingFeature = me; view.addRowTpl(Ext.XTemplate.getTpl(me, 'groupRowTpl')).groupingFeature = me; view.preserveScrollOnRefresh = true; if (store.isBufferedStore) { me.collapsible = false; } else { lockPartner = me.lockingPartner; if (lockPartner && lockPartner.dataSource) { me.dataSource = view.dataSource = dataSource = lockPartner.dataSource; } else { me.dataSource = view.dataSource = dataSource = new Ext.grid.feature.GroupStore(me, store); } } grid = grid.ownerLockable || grid; grid.on('beforereconfigure', me.beforeReconfigure, me); view.on({ afterrender: me.afterViewRender, scope: me, single: true }); if (dataSource) { dataSource.on('groupchange', me.onGroupChange, me); } else { me.setupStoreListeners(store); } }, getGridStore: function() { return this.view.getStore(); }, indexOf: function(record) { return this.dataSource.indexOf(record); }, isInCollapsedGroup: function(record) { var me = this, store = me.getGridStore(), result = false, metaGroup; if (store.isGrouped() && (metaGroup = me.getMetaGroup(record))) { result = !!(metaGroup && metaGroup.isCollapsed); } return result; }, createCache: function() { var metaGroupCache = this.metaGroupCache = {}, lockingPartner = this.lockingPartner; if (lockingPartner) { lockingPartner.metaGroupCache = metaGroupCache; } return metaGroupCache; }, getCache: function() { return this.metaGroupCache || this.createCache(); }, invalidateCache: function() { var lockingPartner = this.lockingPartner; this.metaGroupCache = null; if (lockingPartner) { lockingPartner.metaGroupCache = null; } }, vetoEvent: function(record, row, rowIndex, e) { if (e.type !== 'mouseover' && e.type !== 'mouseout' && e.type !== 'mouseenter' && e.type !== 'mouseleave' && e.getTarget(this.eventSelector)) { return false; } }, enable: function() { var me = this, view = me.view, store = me.getGridStore(), currentGroupedHeader = me.hideGroupedHeader && me.getGroupedHeader(), groupToggleMenuItem; view.isGrouping = true; if (view.lockingPartner) { view.lockingPartner.isGrouping = true; } me.callParent(); if (me.lastGrouper) { store.group(me.lastGrouper); me.lastGrouper = null; } if (currentGroupedHeader) { currentGroupedHeader.hide(); } groupToggleMenuItem = me.view.headerCt.getMenu().down('#groupToggleMenuItem'); if (groupToggleMenuItem) { groupToggleMenuItem.setChecked(true, true); } }, disable: function() { var me = this, view = me.view, store = me.getGridStore(), currentGroupedHeader = me.hideGroupedHeader && me.getGroupedHeader(), lastGrouper = store.getGrouper(), groupToggleMenuItem; view.isGrouping = false; if (view.lockingPartner) { view.lockingPartner.isGrouping = false; } me.callParent(); if (lastGrouper) { me.lastGrouper = lastGrouper; store.clearGrouping(); } if (currentGroupedHeader) { currentGroupedHeader.show(); } groupToggleMenuItem = me.view.headerCt.getMenu().down('#groupToggleMenuItem'); if (groupToggleMenuItem) { groupToggleMenuItem.setChecked(false, true); groupToggleMenuItem.disable(); } }, afterViewRender: function() { var me = this, view = me.view; view.on({ scope: me, groupclick: me.onGroupClick }); if (me.enableGroupingMenu) { me.injectGroupingMenu(); } me.pruneGroupedHeader(); me.lastGrouper = me.getGridStore().getGrouper(); if (me.disabled) { me.disable(); } }, injectGroupingMenu: function() { var me = this, headerCt = me.view.headerCt; headerCt.showMenuBy = me.showMenuBy; headerCt.getMenuItems = me.getMenuItems(); }, onColumnHideShow: function(headerOwnerCt, header) { var me = this, view = me.view, headerCt = view.headerCt, menu = headerCt.getMenu(), activeHeader = menu.activeHeader, groupMenuItem = menu.down('#groupMenuItem'), groupMenuMeth, colCount = me.grid.getVisibleColumnManager().getColumns().length, items, len, i; if (activeHeader && groupMenuItem) { groupMenuMeth = activeHeader.groupable === false || !activeHeader.dataIndex || me.view.headerCt.getVisibleGridColumns().length < 2 ? 'disable' : 'enable'; groupMenuItem[groupMenuMeth](); } if (view.rendered && colCount) { items = view.el.query('.' + me.ctCls); for (i = 0 , len = items.length; i < len; ++i) { items[i].colSpan = colCount; } } }, onColumnMove: function() { var me = this, view = me.view, groupName, groupNames, group, firstRec, lastRec, metaGroup; if (view.getStore().isGrouped()) { groupNames = me.getCache().map; Ext.suspendLayouts(); for (groupName in groupNames) { group = me.getGroup(groupName); firstRec = group.first(); lastRec = group.last(); metaGroup = me.getMetaGroup(groupName); if (metaGroup.isCollapsed) { firstRec = lastRec = me.dataSource.getGroupPlaceholder(groupName); } view.refreshNode(firstRec); if (me.showSummaryRow && lastRec !== firstRec) { view.refreshNode(lastRec); } } Ext.resumeLayouts(true); } }, showMenuBy: function(clickEvent, t, header) { var me = this, menu = me.getMenu(), groupMenuItem = menu.down('#groupMenuItem'), groupMenuMeth = header.groupable === false || !header.dataIndex || me.view.headerCt.getVisibleGridColumns().length < 2 ? 'disable' : 'enable', groupToggleMenuItem = menu.down('#groupToggleMenuItem'), isGrouped = me.grid.getStore().isGrouped(); groupMenuItem[groupMenuMeth](); if (groupToggleMenuItem) { groupToggleMenuItem.setChecked(isGrouped, true); groupToggleMenuItem[isGrouped ? 'enable' : 'disable'](); } Ext.grid.header.Container.prototype.showMenuBy.apply(me, arguments); }, getMenuItems: function() { var me = this, groupByText = me.groupByText, disabled = me.disabled || !me.getGroupField(), showGroupsText = me.showGroupsText, enableNoGroups = me.enableNoGroups, getMenuItems = me.view.headerCt.getMenuItems; return function() { var o = getMenuItems.call(this); o.push('-', { iconCls: Ext.baseCSSPrefix + 'group-by-icon', itemId: 'groupMenuItem', text: groupByText, handler: me.onGroupMenuItemClick, scope: me }); if (enableNoGroups) { o.push({ itemId: 'groupToggleMenuItem', text: showGroupsText, checked: !disabled, checkHandler: me.onGroupToggleMenuItemClick, scope: me }); } return o; }; }, onGroupMenuItemClick: function(menuItem, e) { var me = this, menu = menuItem.parentMenu, hdr = menu.activeHeader, view = me.view, store = me.getGridStore(); if (me.disabled) { me.lastGrouper = null; me.block(); me.enable(); me.unblock(); } view.isGrouping = true; store.group(me.getGrouper(hdr.dataIndex) || hdr.dataIndex); me.pruneGroupedHeader(); }, block: function(fromPartner) { var me = this; me.blockRefresh = me.view.blockRefresh = true; if (me.lockingPartner && !fromPartner) { me.lockingPartner.block(true); } }, unblock: function(fromPartner) { var me = this; me.blockRefresh = me.view.blockRefresh = false; if (me.lockingPartner && !fromPartner) { me.lockingPartner.unblock(true); } }, onGroupToggleMenuItemClick: function(menuItem, checked) { this[checked ? 'enable' : 'disable'](); }, pruneGroupedHeader: function() { var me = this, header = me.getGroupedHeader(); if (me.hideGroupedHeader && header) { Ext.suspendLayouts(); if (me.prunedHeader && me.prunedHeader !== header) { me.prunedHeader.show(); } me.prunedHeader = header; if (header.rendered) { header.hide(); } Ext.resumeLayouts(true); } }, getHeaderNode: function(groupName) { var el = this.view.getEl(), nodes, i, len, node; if (el) { groupName = Ext.htmlEncode(groupName); nodes = el.query(this.eventSelector); for (i = 0 , len = nodes.length; i < len; ++i) { node = nodes[i]; if (node.getAttribute('data-groupName') === groupName) { return node; } } } }, getGroup: function(name) { var store = this.getGridStore(), value = name, group; if (store.isGrouped()) { if (name.isModel) { name = name.get(store.getGroupField()); } if (typeof name !== 'string') { name = store.getGrouper().getGroupString(value); } group = store.getGroups().getByKey(name); } return group; }, getGrouper: function(dataIndex) { var groupers = this.groupers; if (!groupers) { return null; } return Ext.Array.findBy(groupers, function(grouper) { return grouper.property === dataIndex; }); }, getGroupField: function() { return this.getGridStore().getGroupField(); }, getMetaGroup: function(group) { var metaGroupCache = this.metaGroupCache || this.createCache(), key, metaGroup; if (group.isModel) { group = this.getGroup(group); } if (group) { key = (typeof group === 'string') ? group : group.getGroupKey(); metaGroup = metaGroupCache[key]; if (!metaGroup) { metaGroup = metaGroupCache[key] = { isCollapsed: false, lastGroup: null, lastGroupGeneration: null, lastFilterGeneration: null, aggregateRecord: new Ext.data.Model() }; if (!metaGroupCache.map) { metaGroupCache.map = {}; } metaGroupCache.map[key] = true; } } return metaGroup; }, isExpanded: function(groupName) { return !this.getMetaGroup(groupName).isCollapsed; }, expand: function(groupName, focus) { this.doCollapseExpand(false, groupName, focus); }, expandAll: function() { var me = this, metaGroupCache = me.getCache(), lockingPartner = me.lockingPartner, groupName; for (groupName in metaGroupCache) { if (metaGroupCache.hasOwnProperty(groupName)) { metaGroupCache[groupName].isCollapsed = false; } } Ext.suspendLayouts(); me.dataSource.onRefresh(); Ext.resumeLayouts(true); for (groupName in metaGroupCache) { if (metaGroupCache.hasOwnProperty(groupName)) { me.afterCollapseExpand(false, groupName); if (lockingPartner) { lockingPartner.afterCollapseExpand(false, groupName); } } } }, collapse: function(groupName, focus) { this.doCollapseExpand(true, groupName, focus); }, isAllCollapsed: function() { var me = this, metaGroupCache = me.getCache(), groupName; for (groupName in metaGroupCache) { if (metaGroupCache.hasOwnProperty(groupName)) { if (!metaGroupCache[groupName].isCollapsed) { return false; } } } return true; }, isAllExpanded: function() { var me = this, metaGroupCache = me.getCache(), groupName; for (groupName in metaGroupCache) { if (metaGroupCache.hasOwnProperty(groupName)) { if (metaGroupCache[groupName].isCollapsed) { return false; } } } return true; }, collapseAll: function() { var me = this, metaGroupCache = me.getCache(), groupName, lockingPartner = me.lockingPartner; for (groupName in metaGroupCache) { if (metaGroupCache.hasOwnProperty(groupName)) { metaGroupCache[groupName].isCollapsed = true; } } Ext.suspendLayouts(); me.dataSource.onRefresh(); if (lockingPartner && !lockingPartner.isAllCollapsed()) { lockingPartner.collapseAll(); } Ext.resumeLayouts(true); for (groupName in metaGroupCache) { if (metaGroupCache.hasOwnProperty(groupName)) { me.afterCollapseExpand(true, groupName); if (lockingPartner) { lockingPartner.afterCollapseExpand(true, groupName); } } } }, doCollapseExpand: function(collapsed, groupName, focus) { var me = this, lockingPartner = me.lockingPartner, group = me.getGroup(groupName); if (me.getMetaGroup(group).isCollapsed !== collapsed) { Ext.suspendLayouts(); if (collapsed) { me.dataSource.collapseGroup(group); } else { me.dataSource.expandGroup(group); } Ext.resumeLayouts(true); me.afterCollapseExpand(collapsed, groupName, focus); if (lockingPartner) { lockingPartner.afterCollapseExpand(collapsed, groupName, false); } } }, afterCollapseExpand: function(collapsed, groupName, focus) { var me = this, view = me.view, bufferedRenderer = view.bufferedRenderer, header; header = me.getHeaderNode(groupName); view.fireEvent(collapsed ? 'groupcollapse' : 'groupexpand', view, header, groupName); if (focus) { if (header) { view.scrollElIntoView(Ext.fly(header).up(view.getItemSelector()), false, true); } else if (bufferedRenderer) { bufferedRenderer.scrollTo(me.getGroup(groupName).getAt(0)); } } }, onGroupChange: function(store, grouper) { if (!grouper) { this.view.ownerGrid.getView().refresh(); } else { this.lastGrouper = grouper; } }, getMenuItem: function(dataIndex) { var view = this.view, header = view.headerCt.down('gridcolumn[dataIndex=' + dataIndex + ']'), menu = view.headerCt.getMenu(); return header ? menu.down('menuitem[headerId=' + header.id + ']') : null; }, onGroupKey: function(keyCode, event) { var me = this, groupName = me.getGroupName(event.target); if (groupName) { me.onGroupClick(me.view, event.target, groupName, event); } }, onGroupClick: function(view, rowElement, groupName, e) { var me = this, metaGroupCache = me.getCache(), groupNames = metaGroupCache.map, groupIsCollapsed = !me.isExpanded(groupName), g; if (me.collapsible) { if (e.ctrlKey) { Ext.suspendLayouts(); for (g in groupNames) { if (g === groupName) { if (groupIsCollapsed) { me.expand(groupName); } } else if (!metaGroupCache[g].isCollapsed) { me.doCollapseExpand(true, g, false); } } Ext.resumeLayouts(true); return; } if (groupIsCollapsed) { me.expand(groupName); } else { me.collapse(groupName); } } }, setupRowData: function(record, idx, rowValues) { var me = this, recordIndex = rowValues.recordIndex, data = me.refreshData, metaGroupCache = me.getCache(), header = data.header, groupField = data.groupField, store = me.getGridStore(), dataSource = me.view.dataSource, column = me.grid.columnManager.getHeaderByDataIndex(groupField), hasRenderer = !!(column && column.renderer), grouper, groupName, prev, next, items; rowValues.isCollapsedGroup = false; rowValues.summaryRecord = rowValues.groupHeaderCls = null; if (data.doGrouping) { grouper = store.getGrouper(); if (record.isCollapsedPlaceholder) { groupName = record.group.getGroupKey(); items = record.group.items; rowValues.isFirstRow = rowValues.isLastRow = true; rowValues.groupHeaderCls = me.hdCollapsedCls; rowValues.isCollapsedGroup = rowValues.needsWrap = true; rowValues.groupName = groupName; rowValues.metaGroupCache = metaGroupCache; metaGroupCache.groupField = groupField; metaGroupCache.name = metaGroupCache.renderedGroupValue = hasRenderer ? column.renderer(metaGroupCache[groupName].raw, {}, record) : groupName; metaGroupCache.groupValue = items[0].get(groupField); metaGroupCache.columnName = header ? header.text : groupField; rowValues.collapsibleCls = me.collapsible ? me.collapsibleCls : me.hdNotCollapsibleCls; metaGroupCache.rows = metaGroupCache.children = items; if (me.showSummaryRow) { rowValues.summaryRecord = data.summaryData[groupName]; } return; } groupName = grouper.getGroupString(record); if (record.group) { items = record.group.items; rowValues.isFirstRow = record === items[0]; rowValues.isLastRow = record === items[items.length - 1]; } else { rowValues.isFirstRow = recordIndex === 0; if (!rowValues.isFirstRow) { prev = store.getAt(recordIndex - 1); if (prev) { rowValues.isFirstRow = !prev.isEqual(grouper.getGroupString(prev), groupName); } } rowValues.isLastRow = recordIndex === (store.isBufferedStore ? store.getTotalCount() : store.getCount()) - 1; if (!rowValues.isLastRow) { next = store.getAt(recordIndex + 1); if (next) { rowValues.isLastRow = !next.isEqual(grouper.getGroupString(next), groupName); } } } if (rowValues.isFirstRow) { metaGroupCache.groupField = groupField; metaGroupCache.name = metaGroupCache.renderedGroupValue = hasRenderer ? column.renderer(metaGroupCache[groupName].raw, {}, record) : groupName; metaGroupCache.groupValue = record.get(groupField); metaGroupCache.columnName = header ? header.text : groupField; rowValues.collapsibleCls = me.collapsible ? me.collapsibleCls : me.hdNotCollapsibleCls; rowValues.groupName = groupName; if (!me.isExpanded(groupName)) { rowValues.itemClasses.push(me.hdCollapsedCls); rowValues.isCollapsedGroup = true; } if (dataSource.isBufferedStore) { metaGroupCache.rows = metaGroupCache.children = []; } else { metaGroupCache.rows = metaGroupCache.children = me.getRecordGroup(record).items; } rowValues.metaGroupCache = metaGroupCache; } if (rowValues.isLastRow) { if (me.showSummaryRow) { rowValues.summaryRecord = data.summaryData[groupName]; rowValues.itemClasses.push(Ext.baseCSSPrefix + 'grid-group-last'); } } rowValues.needsWrap = (rowValues.isFirstRow || rowValues.summaryRecord); } }, setup: function(rows, rowValues) { var me = this, data = me.refreshData, view = rowValues.view, isGrouping = view.isGrouping = !me.disabled && me.getGridStore().isGrouped(), bufferedRenderer = view.bufferedRenderer; me.skippedRows = 0; if (bufferedRenderer) { bufferedRenderer.variableRowHeight = view.bufferedRenderer.variableRowHeight || isGrouping; } data.groupField = me.getGroupField(); data.header = me.getGroupedHeader(data.groupField); data.doGrouping = isGrouping; rowValues.groupHeaderTpl = Ext.XTemplate.getTpl(me, 'groupHeaderTpl'); if (isGrouping && me.showSummaryRow) { data.summaryData = me.generateSummaryData(); } }, cleanup: function(rows, rowValues) { var data = this.refreshData; rowValues.metaGroupCache = rowValues.groupHeaderTpl = rowValues.isFirstRow = null; data.groupField = data.header = null; }, getAggregateRecord: function(metaGroup, forceNew) { var rec; if (forceNew === true || !metaGroup.aggregateRecord) { rec = new Ext.data.Model(); metaGroup.aggregateRecord = rec; rec.isNonData = rec.isSummary = true; } return metaGroup.aggregateRecord; }, generateSummaryData: function() { var me = this, store = me.getGridStore(), filters = store.getFilters(), groups = store.getGroups().items, reader = store.getProxy().getReader(), groupField = me.getGroupField(), lockingPartner = me.lockingPartner, updateNext = me.updateNext, data = {}, ownerCt = me.view.ownerCt, i, len, group, metaGroup, record, hasRemote, remoteData; if (me.remoteRoot && reader.rawData) { hasRemote = true; remoteData = me.mixins.summary.generateSummaryData.call(me, groupField); } for (i = 0 , len = groups.length; i < len; ++i) { group = groups[i]; metaGroup = me.getMetaGroup(group); if (updateNext || hasRemote || store.updating || me.didGroupChange(group, metaGroup, filters)) { record = me.populateRecord(group, metaGroup, remoteData); if (!lockingPartner || (ownerCt === ownerCt.ownerLockable.normalGrid)) { metaGroup.lastGroup = group; metaGroup.lastGroupGeneration = group.generation; metaGroup.lastFilterGeneration = filters.generation; } } else { record = me.getAggregateRecord(metaGroup); } data[group.getGroupKey()] = record; } me.updateNext = false; return data; }, getGroupName: function(element) { var me = this, view = me.view, eventSelector = me.eventSelector, targetEl, row; targetEl = Ext.fly(element).findParent(eventSelector); if (!targetEl) { row = Ext.fly(element).findParent(view.itemSelector); if (row) { targetEl = row.down(eventSelector, true); } } if (targetEl) { return Ext.htmlDecode(targetEl.getAttribute('data-groupname')); } }, getRecordGroup: function(record) { var store = this.getGridStore(), grouper = store.getGrouper(); if (grouper) { return store.getGroups().getByKey(grouper.getGroupString(record)); } }, getGroupedHeader: function(groupField) { var me = this, headerCt = me.view.headerCt, partner = me.lockingPartner, selector, header; groupField = groupField || me.getGroupField(); if (groupField) { selector = '[dataIndex=' + groupField + ']'; header = headerCt.down(selector); if (!header && partner) { header = partner.view.headerCt.down(selector); } } return header || null; }, getFireEventArgs: function(type, view, targetEl, e) { return [ type, view, targetEl, this.getGroupName(targetEl), e ]; }, destroy: function() { var me = this, dataSource = me.dataSource; me.storeListeners = Ext.destroy(me.storeListeners); me.view = me.prunedHeader = me.grid = me.dataSource = me.groupers = null; me.invalidateCache(); me.callParent(); if (dataSource) { dataSource.bindStore(null); Ext.destroy(dataSource); } }, beforeReconfigure: function(grid, store, columns, oldStore, oldColumns) { var me = this, view = me.view, dataSource = me.dataSource, bufferedStore; if (store && store !== oldStore) { bufferedStore = store.isBufferedStore; if (!dataSource) { Ext.destroy(me.storeListeners); me.setupStoreListeners(store); } if (bufferedStore !== oldStore.isBufferedStore) { Ext.Error.raise('Cannot reconfigure grouping switching between buffered and non-buffered stores'); } view.isGrouping = !!store.getGrouper(); dataSource.bindStore(store); } }, populateRecord: function(group, metaGroup, remoteData) { var me = this, view = me.grid.ownerLockable ? me.grid.ownerLockable.view : me.view, store = me.getGridStore(), record = me.getAggregateRecord(metaGroup), columns = view.headerCt.getGridColumns(), len = columns.length, groupName = group.getGroupKey(), groupData, field, i, column, fieldName, summaryValue; record.beginEdit(); if (remoteData) { groupData = remoteData[groupName]; for (field in groupData) { if (groupData.hasOwnProperty(field)) { if (field !== record.idProperty) { record.set(field, groupData[field]); } } } } for (i = 0; i < len; ++i) { column = columns[i]; fieldName = column.dataIndex || column.getItemId(); if (!remoteData) { summaryValue = me.getSummary(store, column.summaryType, fieldName, group); record.set(fieldName, summaryValue); } else { summaryValue = record.get(column.dataIndex); } me.setSummaryData(record, column.getItemId(), summaryValue, groupName); } record.ownerGroup = groupName; record.endEdit(true); record.commit(); return record; }, privates: { didGroupChange: function(group, metaGroup, filters) { var ret = true; if (group === metaGroup.lastGroup) { ret = metaGroup.lastGroupGeneration !== group.generation || metaGroup.lastFilterGeneration !== filters.generation; } return ret; }, setupStoreListeners: function(store) { var me = this; me.storeListeners = store.on({ groupchange: me.onGroupChange, scope: me, destroyable: true }); } } }); Ext.define('Ext.grid.feature.GroupingSummary', { extend: 'Ext.grid.feature.Grouping', alias: 'feature.groupingsummary', showSummaryRow: true, vetoEvent: function(record, row, rowIndex, e) { var result = this.callParent(arguments); if (result !== false && e.getTarget(this.summaryRowSelector)) { result = false; } return result; } }); Ext.define('Ext.grid.feature.RowBody', { extend: 'Ext.grid.feature.Feature', alias: 'feature.rowbody', rowBodyCls: Ext.baseCSSPrefix + 'grid-row-body', rowBodyHiddenCls: Ext.baseCSSPrefix + 'grid-row-body-hidden', rowBodyTdSelector: 'td.' + Ext.baseCSSPrefix + 'grid-cell-rowbody', eventPrefix: 'rowbody', eventSelector: 'tr.' + Ext.baseCSSPrefix + 'grid-rowbody-tr', colSpanDecrement: 0, bodyBefore: false, outerTpl: { fn: function(out, values, parent) { var view = values.view, rowValues = view.rowValues; this.rowBody.setup(values.rows, rowValues); this.nextTpl.applyOut(values, out, parent); this.rowBody.cleanup(values.rows, rowValues); }, priority: 100 }, extraRowTpl: [ '{%', 'if(this.rowBody.bodyBefore) {', 'values.view.renderColumnSizer(values, out);', '} else {', 'this.nextTpl.applyOut(values, out, parent);', '}', 'values.view.rowBodyFeature.setupRowData(values.record, values.recordIndex, values);', '%}', '', '', '
    {rowBody}
    ', '', '', '{%', 'if(this.rowBody.bodyBefore) {', 'this.nextTpl.applyOut(values, out, parent);', '}', '%}', { priority: 100, beginRowSync: function(rowSync) { rowSync.add('rowBody', this.owner.eventSelector); }, syncContent: function(destRow, sourceRow, columnsToUpdate) { var owner = this.owner, destRowBody = Ext.fly(destRow).down(owner.eventSelector, true), sourceRowBody; if (destRowBody && (sourceRowBody = Ext.fly(sourceRow).down(owner.eventSelector, true))) { Ext.fly(destRowBody).syncContent(sourceRowBody); } } } ], init: function(grid) { var me = this, view = me.view = grid.getView(); grid.variableRowHeight = view.variableRowHeight = true; view.rowBodyFeature = me; grid.mon(view, { element: 'el', click: me.onClick, scope: me }); view.headerCt.on({ columnschanged: me.onColumnsChanged, scope: me }); view.addTpl(me.outerTpl).rowBody = me; view.addRowTpl(Ext.XTemplate.getTpl(this, 'extraRowTpl')).rowBody = me; me.callParent(arguments); }, onClick: function(e) { var me = this, tableRow = e.getTarget(me.eventSelector); if (tableRow && Ext.fly(tableRow = (tableRow.previousSibling || tableRow.nextSibling)).is(me.view.rowSelector)) { e.target = tableRow; me.view.handleEvent(e); } }, getSelectedRow: function(view, rowIndex) { var selectedRow = view.getNode(rowIndex); if (selectedRow) { return Ext.fly(selectedRow).down(this.eventSelector); } return null; }, onColumnsChanged: function(headerCt) { var items = this.view.el.query(this.rowBodyTdSelector), colspan = headerCt.getVisibleGridColumns().length, len = items.length, i; for (i = 0; i < len; ++i) { items[i].setAttribute('colSpan', colspan); } }, setupRowData: function(record, rowIndex, rowValues) { if (this.getAdditionalData) { Ext.apply(rowValues, this.getAdditionalData(record.data, rowIndex, record, rowValues)); } }, setup: function(rows, rowValues) { rowValues.rowBodyCls = this.rowBodyCls; rowValues.rowBodyColspan = this.view.headerCt.visibleColumnManager.getColumns().length - this.colSpanDecrement; }, cleanup: function(rows, rowValues) { rowValues.rowBodyCls = rowValues.rowBodyColspan = rowValues.rowBody = null; } }); Ext.define('Ext.grid.feature.Summary', { extend: 'Ext.grid.feature.AbstractSummary', alias: 'feature.summary', dock: undefined, dockedSummaryCls: Ext.baseCSSPrefix + 'docked-summary', panelBodyCls: Ext.baseCSSPrefix + 'summary-', hasFeatureEvent: false, fullSummaryTpl: [ '{%', 'var me = this.summaryFeature,', ' record = me.summaryRecord,', ' view = values.view,', ' bufferedRenderer = view.bufferedRenderer;', 'this.nextTpl.applyOut(values, out, parent);', 'if (!me.disabled && me.showSummaryRow && view.store.isLast(values.record)) {', 'if (bufferedRenderer) {', ' bufferedRenderer.variableRowHeight = true;', '}', 'me.outputSummaryRecord((record && record.isModel) ? record : me.createSummaryRecord(view), values, out, parent);', '}', '%}', { priority: 300, beginRowSync: function(rowSync) { rowSync.add('fullSummary', this.summaryRowSelector); }, syncContent: function(destRow, sourceRow, columnsToUpdate) { destRow = Ext.fly(destRow, 'syncDest'); sourceRow = Ext.fly(sourceRow, 'sycSrc'); var owner = this.owner, selector = owner.summaryRowSelector, destSummaryRow = destRow.down(selector, true), sourceSummaryRow = sourceRow.down(selector, true); if (destSummaryRow && sourceSummaryRow) { if (columnsToUpdate) { this.summaryFeature.view.updateColumns(destSummaryRow, sourceSummaryRow, columnsToUpdate); } else { Ext.fly(destSummaryRow).syncContent(sourceSummaryRow); } } } } ], init: function(grid) { var me = this, view = me.view, dock = me.dock; me.callParent(arguments); if (dock) { grid.headerCt.on({ add: me.onStoreUpdate, afterlayout: me.onStoreUpdate, scope: me }); grid.on({ beforerender: function() { var tableCls = [ me.summaryTableCls ]; if (view.columnLines) { tableCls[tableCls.length] = view.ownerCt.colLinesCls; } me.summaryBar = grid.addDocked({ childEls: [ 'innerCt', 'item' ], renderTpl: [ '' ], scrollable: { x: false, y: false }, hidden: !me.showSummaryRow, itemId: 'summaryBar', cls: [ me.dockedSummaryCls, me.dockedSummaryCls + '-' + dock ], xtype: 'component', dock: dock, weight: 10000000 })[0]; }, afterrender: function() { grid.body.addCls(me.panelBodyCls + dock); view.on('scroll', me.onViewScroll, me); me.onStoreUpdate(); }, single: true }); grid.headerCt.afterComponentLayout = Ext.Function.createSequence(grid.headerCt.afterComponentLayout, function() { var width = this.getTableWidth(), innerCt = me.summaryBar.innerCt; me.summaryBar.item.setWidth(width); if (this.tooNarrow) { width += Ext.getScrollbarSize().width; } innerCt.setWidth(width); }); } else { if (grid.bufferedRenderer) { me.wrapsItem = true; view.addRowTpl(Ext.XTemplate.getTpl(me, 'fullSummaryTpl')).summaryFeature = me; view.on('refresh', me.onViewRefresh, me); } else { me.wrapsItem = false; me.view.addFooterFn(me.renderSummaryRow); } } grid.on({ beforereconfigure: me.onBeforeReconfigure, columnmove: me.onStoreUpdate, scope: me }); me.bindStore(grid, grid.getStore()); }, onBeforeReconfigure: function(grid, store) { this.summaryRecord = null; if (store) { this.bindStore(grid, store); } }, bindStore: function(grid, store) { var me = this; Ext.destroy(me.storeListeners); me.storeListeners = store.on({ scope: me, destroyable: true, update: me.onStoreUpdate, datachanged: me.onStoreUpdate }); }, renderSummaryRow: function(values, out, parent) { var view = values.view, me = view.findFeature('summary'), record, rows; if (!me.disabled && me.showSummaryRow) { record = me.summaryRecord; out.push(''); me.outputSummaryRecord((record && record.isModel) ? record : me.createSummaryRecord(view), values, out, parent); out.push('
    '); } }, toggleSummaryRow: function(visible, fromLockingPartner) { var me = this, bar = me.summaryBar; me.callParent([ visible, fromLockingPartner ]); if (bar) { bar.setVisible(me.showSummaryRow); me.onViewScroll(); } }, getSummaryBar: function() { return this.summaryBar; }, vetoEvent: function(record, row, rowIndex, e) { return !e.getTarget(this.summaryRowSelector); }, onViewScroll: function() { this.summaryBar.setScrollX(this.view.getScrollX()); }, onViewRefresh: function(view) { var me = this, record, row; if (!me.disabled && me.showSummaryRow && !view.all.getCount()) { record = me.createSummaryRecord(view); row = Ext.fly(view.getNodeContainer()).createChild({ tag: 'table', cellpadding: 0, cellspacing: 0, cls: me.summaryItemCls, style: 'table-layout: fixed; width: 100%' }, false, true); row.appendChild(Ext.fly(view.createRowElement(record, -1)).down(me.summaryRowSelector, true)); } }, createSummaryRecord: function(view) { var me = this, columns = view.headerCt.getVisibleGridColumns(), remoteRoot = me.remoteRoot, summaryRecord = me.summaryRecord, colCount = columns.length, i, column, dataIndex, summaryValue, modelData; if (!summaryRecord) { modelData = { id: view.id + '-summary-record' }; summaryRecord = me.summaryRecord = new Ext.data.Model(modelData); } summaryRecord.beginEdit(); if (remoteRoot && view.store.proxy.reader.rawData) { summaryRecord.set(me.generateSummaryData()); } else if (!remoteRoot) { for (i = 0; i < colCount; i++) { column = columns[i]; dataIndex = column.dataIndex || column.getItemId(); summaryValue = me.getSummary(view.store, column.summaryType, dataIndex); summaryRecord.set(dataIndex, summaryValue); me.setSummaryData(summaryRecord, column.getItemId(), summaryValue); } } summaryRecord.endEdit(true); summaryRecord.commit(true); summaryRecord.isSummary = true; return summaryRecord; }, onStoreUpdate: function() { var me = this, view = me.view, selector = me.summaryRowSelector, dock = me.dock, record, newRowDom, oldRowDom, p; if (!view.rendered) { return; } record = me.createSummaryRecord(view); newRowDom = Ext.fly(view.createRowElement(record, -1)).down(selector, true); if (!newRowDom) { return; } if (dock) { p = me.summaryBar.item.dom.firstChild; oldRowDom = p.firstChild; } else { oldRowDom = me.view.el.down(selector, true); p = oldRowDom ? oldRowDom.parentNode : null; } if (p) { p.insertBefore(newRowDom, oldRowDom); p.removeChild(oldRowDom); } if (dock) { me.onColumnHeaderLayout(); } }, onColumnHeaderLayout: function() { var view = this.view, columns = view.headerCt.getVisibleGridColumns(), column, len = columns.length, i, summaryEl = this.summaryBar.el, el; for (i = 0; i < len; i++) { column = columns[i]; el = summaryEl.down(view.getCellSelector(column), true); if (el) { Ext.fly(el).setWidth(column.width || (column.lastBox ? column.lastBox.width : 100)); } } }, destroy: function() { var me = this; me.summaryRecord = me.storeListeners = Ext.destroy(me.storeListeners); me.callParent(); } }); Ext.define('Ext.menu.Item', { extend: 'Ext.Component', alias: 'widget.menuitem', alternateClassName: 'Ext.menu.TextItem', isMenuItem: true, mixins: [ 'Ext.mixin.Queryable' ], activated: false, activeCls: Ext.baseCSSPrefix + 'menu-item-active', ariaRole: 'menuitem', clickHideDelay: 0, destroyMenu: true, disabledCls: Ext.baseCSSPrefix + 'menu-item-disabled', hideOnClick: true, menuAlign: 'tl-tr?', menuExpandDelay: 200, menuHideDelay: 200, tooltipType: 'qtip', focusable: true, baseCls: Ext.baseCSSPrefix + 'menu-item', arrowCls: Ext.baseCSSPrefix + 'menu-item-arrow', baseIconCls: Ext.baseCSSPrefix + 'menu-item-icon', textCls: Ext.baseCSSPrefix + 'menu-item-text', indentCls: Ext.baseCSSPrefix + 'menu-item-indent', indentNoSeparatorCls: Ext.baseCSSPrefix + 'menu-item-indent-no-separator', indentRightIconCls: Ext.baseCSSPrefix + 'menu-item-indent-right-icon', indentRightArrowCls: Ext.baseCSSPrefix + 'menu-item-indent-right-arrow', linkCls: Ext.baseCSSPrefix + 'menu-item-link', linkHrefCls: Ext.baseCSSPrefix + 'menu-item-link-href', childEls: [ 'itemEl', 'iconEl', 'textEl', 'arrowEl' ], renderTpl: '' + '{text}' + '' + ' {linkHrefCls}{childElCls}"' + ' href="{href}" role="menuitem" ' + ' target="{hrefTarget}"' + ' hidefocus="true"' + ' unselectable="on"' + '' + ' tabindex="{tabIndex}"' + '' + '>' + '{text}' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '', maskOnDisable: false, iconAlign: 'left', canFocus: function() { var me = this; return me.focusable && me.rendered && me.canActivate !== false && !me.destroying && !me.isDestroyed && me.isVisible(true); }, onFocus: function(e) { var me = this; me.callParent([ e ]); if (!me.disabled) { if (!me.plain) { me.addCls(me.activeCls); } me.activated = true; if (me.hasListeners.activate) { me.fireEvent('activate', me); } } }, onFocusLeave: function(e) { var me = this; me.callParent([ e ]); if (me.activated) { if (!me.plain) { me.removeCls(me.activeCls); } me.doHideMenu(); me.activated = false; if (me.hasListeners.deactivate) { me.fireEvent('deactivate', me); } } }, doHideMenu: function() { var menu = this.menu; this.cancelDeferExpand(); if (menu && menu.isVisible()) { menu.hide(); } }, deferHideParentMenus: function() { var topMenu = this.getRefOwner(); if (topMenu.floating) { topMenu.bubble(function(parent) { if (!parent.floating && !parent.isMenuItem) { return false; } if (parent.isMenu) { topMenu = parent; } }); topMenu.hide(); } }, expandMenu: function(event, delay) { var me = this; if (me.activated && me.menu) { me.hideOnClick = false; me.cancelDeferHide(); delay = delay == null ? me.menuExpandDelay : delay; if (delay === 0) { me.doExpandMenu(event); } else { me.cancelDeferExpand(); me.expandMenuTimer = Ext.defer(me.doExpandMenu, delay, me, [ event ]); } } }, doExpandMenu: function(clickEvent) { var me = this, menu = me.menu; if (!menu.isVisible()) { me.parentMenu.activeChild = menu; menu.ownerCmp = me; menu.parentMenu = me.parentMenu; menu.constrainTo = document.body; menu.autoFocus = !clickEvent || !clickEvent.pointerType; menu.showBy(me, me.menuAlign); } }, getRefItems: function(deep) { var menu = this.menu, items; if (menu) { items = menu.getRefItems(deep); items.unshift(menu); } return items || []; }, getValue: function() { return this.value; }, hideMenu: function(delay) { var me = this; if (me.menu) { me.cancelDeferExpand(); me.hideMenuTimer = Ext.defer(me.doHideMenu, Ext.isNumber(delay) ? delay : me.menuHideDelay, me); } }, initComponent: function() { var me = this, cls = me.cls ? [ me.cls ] : [], menu; if (me.hasOwnProperty('canActivate')) { me.focusable = me.canActivate; } if (me.plain) { cls.push(Ext.baseCSSPrefix + 'menu-item-plain'); } if (cls.length) { me.cls = cls.join(' '); } if (me.menu) { menu = me.menu; me.menu = null; me.setMenu(menu); } me.callParent(arguments); }, onClick: function(e) { var me = this, clickHideDelay = me.clickHideDelay, browserEvent = e.browserEvent, clickResult, preventDefault; if (!me.href || me.disabled) { e.stopEvent(); if (me.disabled) { return false; } } if (me.disabled || me.handlingClick) { return; } if (me.hideOnClick) { if (!clickHideDelay) { me.deferHideParentMenus(); } else { me.deferHideParentMenusTimer = Ext.defer(me.deferHideParentMenus, clickHideDelay, me); } } clickResult = me.fireEvent('click', me, e); if (me.isDestroyed) { return; } if (clickResult !== false && me.handler) { Ext.callback(me.handler, me.scope, [ me, e ], 0, me); } if (Ext.isIE9m) { preventDefault = browserEvent.returnValue === false ? true : false; } else { preventDefault = !!browserEvent.defaultPrevented; } if (me.href && e.type !== 'click' && !preventDefault) { me.handlingClick = true; me.itemEl.dom.click(); me.handlingClick = false; } if (!me.hideOnClick) { me.focus(); } return clickResult; }, onRemoved: function() { var me = this; if (me.activated && me.parentMenu.activeItem === me) { me.parentMenu.deactivateActiveItem(); } me.callParent(arguments); me.parentMenu = me.ownerCmp = null; }, beforeDestroy: function() { var me = this; if (me.rendered) { me.clearTip(); } me.callParent(); }, onDestroy: function() { var me = this; me.cancelDeferExpand(); me.cancelDeferHide(); clearTimeout(me.deferHideParentMenusTimer); me.setMenu(null); me.callParent(arguments); }, beforeRender: function() { var me = this, glyph = me.glyph, glyphFontFamily = Ext._glyphFontFamily, hasIcon = !!(me.icon || me.iconCls || glyph), hasMenu = !!me.menu, rightIcon = ((me.iconAlign === 'right') && !hasMenu), isCheckItem = me.isMenuCheckItem, indentCls = [], ownerCt = me.ownerCt, isOwnerPlain = ownerCt.plain, glyphParts; me.callParent(); if (hasIcon) { if (hasMenu && me.showCheckbox) { hasIcon = false; } } if (typeof glyph === 'string') { glyphParts = glyph.split('@'); glyph = glyphParts[0]; glyphFontFamily = glyphParts[1]; } if (!isOwnerPlain || (hasIcon && !rightIcon) || isCheckItem) { if (ownerCt.showSeparator && !isOwnerPlain) { indentCls.push(me.indentCls); } else { indentCls.push(me.indentNoSeparatorCls); } } if (hasMenu) { indentCls.push(me.indentRightArrowCls); } else if (hasIcon && (rightIcon || isCheckItem)) { indentCls.push(me.indentRightIconCls); } Ext.applyIf(me.renderData, { hasHref: !!me.href, href: me.href || '#', hrefTarget: me.hrefTarget, icon: me.icon, iconCls: me.iconCls, glyph: glyph, glyphCls: glyph ? Ext.baseCSSPrefix + 'menu-item-glyph' : undefined, glyphFontFamily: glyphFontFamily, hasIcon: hasIcon, hasMenu: hasMenu, indent: !isOwnerPlain || hasIcon || isCheckItem, isCheckItem: isCheckItem, rightIcon: rightIcon, plain: me.plain, text: me.text, arrowCls: me.arrowCls, baseIconCls: me.baseIconCls, textCls: me.textCls, indentCls: indentCls.join(' '), linkCls: me.linkCls, linkHrefCls: me.linkHrefCls, groupCls: me.group ? me.groupCls : '', tabIndex: me.tabIndex }); }, onRender: function() { var me = this; me.callParent(arguments); if (me.tooltip) { me.setTooltip(me.tooltip, true); } }, getMenu: function() { return this.menu || null; }, setMenu: function(menu, destroyMenu) { var me = this, oldMenu = me.menu, arrowEl = me.arrowEl, instanced; if (oldMenu) { oldMenu.ownerCmp = oldMenu.parentMenu = null; if (destroyMenu === true || (destroyMenu !== false && me.destroyMenu)) { Ext.destroy(oldMenu); } } if (menu) { instanced = menu.isMenu; menu = me.menu = Ext.menu.Manager.get(menu, { ownerCmp: me, focusOnToFront: false }); menu.setOwnerCmp(me, instanced); } else { menu = me.menu = null; } if (menu && me.rendered && !me.destroying && arrowEl) { arrowEl[menu ? 'addCls' : 'removeCls'](me.arrowCls); } }, setHandler: function(fn, scope) { this.handler = fn || null; this.scope = scope; }, setIcon: function(icon) { var iconEl = this.iconEl, oldIcon = this.icon; if (iconEl) { iconEl.src = icon || Ext.BLANK_IMAGE_URL; } this.icon = icon; this.fireEvent('iconchange', this, oldIcon, icon); }, setIconCls: function(iconCls) { var me = this, iconEl = me.iconEl, oldCls = me.iconCls; if (iconEl) { if (me.iconCls) { iconEl.removeCls(me.iconCls); } if (iconCls) { iconEl.addCls(iconCls); } } me.iconCls = iconCls; me.fireEvent('iconchange', me, oldCls, iconCls); }, setText: function(text) { var me = this, el = me.textEl || me.el, oldText = me.text; me.text = text; if (me.rendered) { el.setHtml(text || ''); me.updateLayout(); } me.fireEvent('textchange', me, oldText, text); }, getTipAttr: function() { return this.tooltipType === 'qtip' ? 'data-qtip' : 'title'; }, clearTip: function() { if (Ext.quickTipsActive && Ext.isObject(this.tooltip)) { Ext.tip.QuickTipManager.unregister(this.itemEl); } }, setTooltip: function(tooltip, initial) { var me = this; if (me.rendered) { if (!initial) { me.clearTip(); } if (Ext.quickTipsActive && Ext.isObject(tooltip)) { Ext.tip.QuickTipManager.register(Ext.apply({ target: me.itemEl.id }, tooltip)); me.tooltip = tooltip; } else { me.itemEl.dom.setAttribute(me.getTipAttr(), tooltip); } } else { me.tooltip = tooltip; } return me; }, privates: { cancelDeferExpand: function() { window.clearTimeout(this.expandMenuTimer); }, cancelDeferHide: function() { window.clearTimeout(this.hideMenuTimer); }, getFocusEl: function() { return this.itemEl; } } }); Ext.define('Ext.menu.CheckItem', { extend: 'Ext.menu.Item', alias: 'widget.menucheckitem', checkedCls: Ext.baseCSSPrefix + 'menu-item-checked', uncheckedCls: Ext.baseCSSPrefix + 'menu-item-unchecked', groupCls: Ext.baseCSSPrefix + 'menu-group-icon', hideOnClick: false, checkChangeDisabled: false, ariaRole: 'menuitemcheckbox', childEls: [ 'checkEl' ], showCheckbox: true, isMenuCheckItem: true, checkboxCls: Ext.baseCSSPrefix + 'menu-item-checkbox', initComponent: function() { var me = this; me.checked = !!me.checked; me.callParent(arguments); if (me.group) { Ext.menu.Manager.registerCheckable(me); if (me.initialConfig.hideOnClick !== false) { me.hideOnClick = true; } } }, beforeRender: function() { var me = this; me.callParent(); Ext.apply(me.renderData, { checkboxCls: me.checkboxCls, showCheckbox: me.showCheckbox }); }, afterRender: function() { var me = this; me.callParent(); me.checked = !me.checked; me.setChecked(!me.checked, true); if (me.checkChangeDisabled) { me.disableCheckChange(); } }, disableCheckChange: function() { var me = this, checkEl = me.checkEl; if (checkEl) { checkEl.addCls(me.disabledCls); } if (Ext.isIE8 && me.rendered) { me.el.repaint(); } me.checkChangeDisabled = true; }, enableCheckChange: function() { var me = this, checkEl = me.checkEl; if (checkEl) { checkEl.removeCls(me.disabledCls); } me.checkChangeDisabled = false; }, onClick: function(e) { var me = this; if (!me.disabled && !me.checkChangeDisabled && !(me.checked && me.group)) { me.setChecked(!me.checked); if (e.type === 'keydown' && me.menu) { return false; } } this.callParent([ e ]); }, onDestroy: function() { Ext.menu.Manager.unregisterCheckable(this); this.callParent(arguments); }, setChecked: function(checked, suppressEvents) { var me = this, checkedCls = me.checkedCls, uncheckedCls = me.uncheckedCls, el = me.el; if (me.checked !== checked && (suppressEvents || me.fireEvent('beforecheckchange', me, checked) !== false)) { if (el) { if (checked) { el.addCls(checkedCls); el.removeCls(uncheckedCls); } else { el.addCls(uncheckedCls); el.removeCls(checkedCls); } } me.checked = checked; Ext.menu.Manager.onCheckChange(me, checked); if (!suppressEvents) { Ext.callback(me.checkHandler, me.scope || me, [ me, checked ]); me.fireEvent('checkchange', me, checked); } } } }); Ext.define('Ext.menu.Separator', { extend: 'Ext.menu.Item', alias: 'widget.menuseparator', focusable: false, canActivate: false, hideOnClick: false, plain: true, separatorCls: Ext.baseCSSPrefix + 'menu-item-separator', text: ' ', ariaRole: 'separator', beforeRender: function(ct, pos) { var me = this; me.callParent(); me.addCls(me.separatorCls); } }); Ext.define('Ext.menu.Menu', { extend: 'Ext.panel.Panel', alias: 'widget.menu', requires: [ 'Ext.layout.container.VBox', 'Ext.menu.CheckItem', 'Ext.menu.Item', 'Ext.menu.Manager', 'Ext.menu.Separator' ], mixins: [ 'Ext.util.FocusableContainer' ], enableKeyNav: true, allowOtherMenus: false, ariaRole: 'menu', floating: true, constrain: true, hidden: true, hideMode: 'visibility', ignoreParentClicks: false, isMenu: true, showSeparator: true, minWidth: undefined, defaultMinWidth: 120, defaultAlign: 'tl-bl?', focusOnToFront: false, bringParentToFront: false, defaultFocus: ':focusable', menuClickBuffer: 0, baseCls: Ext.baseCSSPrefix + 'menu', _iconSeparatorCls: Ext.baseCSSPrefix + 'menu-icon-separator', _itemCmpCls: Ext.baseCSSPrefix + 'menu-item-cmp', layout: { type: 'vbox', align: 'stretchmax', overflowHandler: 'Scroller' }, initComponent: function() { var me = this, cls = [ Ext.baseCSSPrefix + 'menu' ], bodyCls = me.bodyCls ? [ me.bodyCls ] : [], isFloating = me.floating !== false, listeners = { element: 'el', click: me.onClick, mouseover: me.onMouseOver, scope: me }; if (Ext.supports.Touch) { listeners.pointerdown = me.onMouseOver; } me.on(listeners); me.on({ beforeshow: me.onBeforeShow, scope: me }); if (me.plain) { cls.push(Ext.baseCSSPrefix + 'menu-plain'); } me.cls = cls.join(' '); bodyCls.push(Ext.baseCSSPrefix + 'menu-body', Ext.dom.Element.unselectableCls); me.bodyCls = bodyCls.join(' '); if (isFloating) { if (me.minWidth === undefined) { me.minWidth = me.defaultMinWidth; } } else { me.hidden = !!me.initialConfig.hidden; me.constrain = false; } me.callParent(arguments); Ext.override(me.getLayout(), { configureItem: me.configureItem }); }, initFloatConstrain: Ext.emptyFn, getInherited: function() { var result = this.callParent(); result.hidden = this.hidden; return result; }, beforeRender: function() { this.callParent(arguments); if (!this.getSizeModel().width.shrinkWrap) { this.layout.align = 'stretch'; } }, onBoxReady: function() { var me = this, iconSeparatorCls = me._iconSeparatorCls; me.focusableKeyNav.map.processEvent = function(e) { if (e.keyCode === e.ESC) { e.target = me.el.dom; } return e; }; me.focusableKeyNav.map.addBinding([ { key: 27, handler: me.onEscapeKey, scope: me }, { key: /[\w]/, handler: me.onShortcutKey, scope: me, shift: false, ctrl: false, alt: false } ]); me.callParent(arguments); if (me.showSeparator) { me.iconSepEl = me.body.insertFirst({ role: 'presentation', cls: iconSeparatorCls + ' ' + iconSeparatorCls + '-' + me.ui, html: ' ' }); } if (Ext.supports.MSPointerEvents || Ext.supports.PointerEvents) { me.el.on({ scope: me, click: me.preventClick, translate: false }); } me.mouseMonitor = me.el.monitorMouseLeave(100, me.onMouseLeave, me); }, onFocusLeave: function(e) { var me = this; me.callParent([ e ]); me.mixins.focusablecontainer.onFocusLeave.call(me, e); if (me.floating) { me.hide(); } }, canActivateItem: function(item) { return item && item.isFocusable(); }, deactivateActiveItem: function() { var me = this, activeItem = me.lastFocusedChild; if (activeItem) { activeItem.blur(); } }, getItemFromEvent: function(e) { var me = this, renderTarget = me.layout.getRenderTarget().dom, toEl = e.getTarget(); while (toEl.parentNode !== renderTarget) { toEl = toEl.parentNode; if (!toEl) { return; } } return Ext.getCmp(toEl.id); }, lookupComponent: function(cmp) { var me = this; if (typeof cmp === 'string') { cmp = me.lookupItemFromString(cmp); } else if (Ext.isObject(cmp)) { cmp = me.lookupItemFromObject(cmp); } if (!cmp.dock) { cmp.minWidth = cmp.minWidth || me.minWidth; } return cmp; }, lookupItemFromObject: function(cmp) { var me = this; 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); } } if (cmp.isMenuItem) { cmp.parentMenu = me; } return cmp; }, lookupItemFromString: function(cmp) { return (cmp === 'separator' || cmp === '-') ? new Ext.menu.Separator() : new Ext.menu.Item({ canActivate: false, hideOnClick: false, plain: true, text: cmp }); }, configureItem: function(cmp) { var me = this.owner, prefix = Ext.baseCSSPrefix, ui = me.ui, cls, cmpCls; if (cmp.isMenuItem) { cmp.setUI(ui); } else if (me.items.getCount() > 1 && !cmp.rendered && !cmp.dock) { cmpCls = me._itemCmpCls; cls = [ cmpCls + ' ' + cmpCls + '-' + ui ]; if (!me.plain && (cmp.indent !== false || cmp.iconCls === 'no-icon')) { cls.push(prefix + 'menu-item-indent-' + ui); } if (cmp.rendered) { cmp.el.addCls(cls); } else { cmp.cls = (cmp.cls || '') + ' ' + cls.join(' '); } cmp.$extraMenuCls = cls; } this.callParent(arguments); }, onRemove: function(cmp) { this.callParent([ cmp ]); if (!cmp.isDestroyed && cmp.$extraMenuCls) { cmp.el.removeCls(cmp.$extraMenuCls); } }, onClick: function(e) { var me = this, type = e.type, item, clickResult, iskeyEvent = type === 'keydown'; if (me.disabled) { e.stopEvent(); return; } item = me.getItemFromEvent(e); if (item && item.isMenuItem) { if (!item.menu || !me.ignoreParentClicks) { clickResult = item.onClick(e); } else { e.stopEvent(); } if (item.menu && clickResult !== false && iskeyEvent) { item.expandMenu(e, 0); } } if (!item || item.disabled) { item = undefined; } me.fireEvent('click', me, item, e); }, onDestroy: function() { var me = this; me.parentMenu = me.ownerCmp = null; if (me.rendered) { me.el.un(me.mouseMonitor); Ext.destroy(me.iconSepEl); } me.callParent(arguments); }, onMouseLeave: function(e) { if (this.disabled) { return; } this.fireEvent('mouseleave', this, e); }, onMouseOver: function(e) { var me = this, fromEl = e.getRelatedTarget(), mouseEnter = !me.el.contains(fromEl), item = me.getItemFromEvent(e), parentMenu = me.parentMenu, ownerCmp = me.ownerCmp; if (mouseEnter && parentMenu) { parentMenu.setActiveItem(ownerCmp); ownerCmp.cancelDeferHide(); parentMenu.mouseMonitor.mouseenter(); } if (me.disabled) { return; } if (item) { if (!item.containsFocus) { item.focus(); } if (item.expandMenu) { item.expandMenu(e); } } if (mouseEnter) { me.fireEvent('mouseenter', me, e); } me.fireEvent('mouseover', me, item, e); }, setActiveItem: function(item) { var me = this; if (item && (item !== me.lastFocusedChild)) { me.focusChild(item, 1); } }, onEscapeKey: function() { if (this.floating) { this.hide(); } }, onShortcutKey: function(keyCode, e) { var shortcutChar = String.fromCharCode(e.getCharCode()), items = this.query('>[text]'), len = items.length, item = this.lastFocusedChild, focusIndex = Ext.Array.indexOf(items, item), i = focusIndex; for (; ; ) { if (++i === len) { i = 0; } item = items[i]; if (i === focusIndex) { return; } if (item.text && item.text[0].toUpperCase() === shortcutChar) { item.focus(); return; } } }, onFocusableContainerTabKey: function(e) { if (this.floating) { this.hide(); } }, onFocusableContainerEnterKey: function(e) { this.onClick(e); }, onFocusableContainerSpaceKey: function(e) { this.onClick(e); }, onFocusableContainerLeftKey: function(e) { if (this.parentMenu) { this.ownerCmp.focus(); this.hide(); } }, onFocusableContainerRightKey: function(e) { var me = this, focusItem = me.lastFocusedChild; if (focusItem && focusItem.expandMenu) { focusItem.expandMenu(e, 0); } }, onBeforeShow: function() { if (Ext.Date.getElapsed(this.lastHide) < this.menuClickBuffer) { return false; } }, beforeShow: function() { var me = this, activeEl, viewHeight; if (me.floating) { if (!me.hasFloatMenuParent() && !me.allowOtherMenus) { Ext.menu.Manager.hideAll(); } activeEl = Ext.Element.getActiveElement(); me.focusAnchor = activeEl === document.body ? null : activeEl; me.savedMaxHeight = me.maxHeight; viewHeight = me.container.getViewSize().height; me.maxHeight = Math.min(me.maxHeight || viewHeight, viewHeight); } me.callParent(arguments); }, afterShow: function() { var me = this; me.callParent(arguments); Ext.menu.Manager.onShow(me); if (me.floating && me.autoFocus) { me.maxHeight = me.savedMaxHeight; me.focus(); } }, onHide: function(animateTarget, cb, scope) { var me = this, focusTarget; if (me.el.contains(Ext.Element.getActiveElement())) { focusTarget = me.focusAnchor || me.ownerCmp || me.up(':focusable'); if (focusTarget) { me.previousFocus = focusTarget; } } me.callParent([ animateTarget, cb, scope ]); me.lastHide = Ext.Date.now(); Ext.menu.Manager.onHide(me); }, preventClick: function(e) { var item = this.getItemFromEvent(e); if (item && !item.href) { e.preventDefault(); } }, privates: { hasFloatMenuParent: function() { return this.parentMenu || this.up('menu[floating=true]'); }, setOwnerCmp: function(comp, instanced) { var me = this; me.parentMenu = comp.isMenuItem ? comp : null; me.ownerCmp = comp; me.registerWithOwnerCt(); delete me.hierarchicallyHidden; if (me.inheritedState && instanced) { me.invalidateInheritedState(); } if (me.reference) { me.fixReference(); } if (instanced) { Ext.ComponentManager.markReferencesDirty(); } } } }); Ext.define('Ext.grid.filters.filter.Base', { mixins: [ 'Ext.mixin.Factoryable' ], factoryConfig: { type: 'grid.filter' }, $configPrefixed: false, $configStrict: false, config: { itemDefaults: null, menuDefaults: { xtype: 'menu' }, updateBuffer: 500 }, active: false, type: 'string', dataIndex: null, menu: null, isGridFilter: true, defaultRoot: 'data', filterIdPrefix: Ext.baseCSSPrefix + 'gridfilter', constructor: function(config) { var me = this, column; me.initConfig(config); column = me.column; column.on('destroy', me.destroy, me); me.dataIndex = me.dataIndex || column.dataIndex; me.task = new Ext.util.DelayedTask(me.setValue, me); }, destroy: function() { this.grid = this.menu = Ext.destroy(this.menu); }, addStoreFilter: function(filter) { this.getGridStore().getFilters().add(filter); }, createFilter: function(config, key) { return new Ext.util.Filter(this.getFilterConfig(config, key)); }, getFilterConfig: function(config, key) { config.id = this.getBaseIdPrefix(); if (!config.property) { config.property = this.dataIndex; } if (!config.root) { config.root = this.defaultRoot; } if (key) { config.id += '-' + key; } return config; }, createMenu: function() { this.menu = Ext.widget(this.getMenuConfig()); }, getActiveState: function(config, value) { var active = config.active; return (active !== undefined) ? active : value !== undefined; }, getBaseIdPrefix: function() { return this.filterIdPrefix + '-' + this.dataIndex; }, getMenuConfig: function() { return Ext.apply({}, this.getMenuDefaults()); }, getGridStore: function() { return this.grid.getStore(); }, getStoreFilter: function(key) { var id = this.getBaseIdPrefix(); if (key) { id += '-' + key; } return this.getGridStore().getFilters().get(id); }, onValueChange: function(field, e) { var me = this, updateBuffer = me.updateBuffer; if (!field.isFormField) { Ext.Error.raise('`field` should be a form field instance.'); } if (field.isValid()) { if (e.getKey() === e.RETURN) { me.menu.hide(); return; } if (updateBuffer) { me.task.delay(updateBuffer, null, null, [ me.getValue(field) ]); } else { me.setValue(me.getValue(field)); } } }, preprocess: Ext.emptyFn, removeStoreFilter: function(filter) { this.getGridStore().getFilters().remove(filter); }, getValue: Ext.emptyFn, setActive: function(active) { var me = this, menuItem = me.owner.activeFilterMenuItem, filterCollection; if (me.active !== active) { me.active = active; me.preventDefault = true; filterCollection = me.getGridStore().getFilters(); filterCollection.beginUpdate(); if (active) { me.activate(); } else { me.deactivate(); } filterCollection.endUpdate(); me.preventDefault = false; if (menuItem && menuItem.activeFilter === me) { menuItem.setChecked(active); } me.setColumnActive(active); } }, setColumnActive: function(active) { this.column[active ? 'addCls' : 'removeCls'](this.owner.filterCls); }, showMenu: function(menuItem) { var me = this; if (!me.menu) { me.createMenu(); } menuItem.activeFilter = me; menuItem.setMenu(me.menu, false); menuItem.setChecked(me.active); menuItem.setDisabled(me.disabled === true); me.activate( true); }, updateStoreFilter: function() { this.getGridStore().getFilters().notify('endupdate'); } }); Ext.define('Ext.grid.filters.filter.SingleFilter', { extend: 'Ext.grid.filters.filter.Base', constructor: function(config) { var me = this, filter, value; me.callParent([ config ]); value = me.value; filter = me.getStoreFilter(); if (filter) { me.active = true; } else { if (me.grid.stateful && me.getGridStore().saveStatefulFilters) { value = undefined; } me.active = me.getActiveState(config, value); filter = me.createFilter({ operator: me.operator, value: value }); if (me.active) { me.addStoreFilter(filter); } } if (me.active) { me.setColumnActive(true); } me.filter = filter; }, activate: function(showingMenu) { if (showingMenu) { this.activateMenu(); } else { this.addStoreFilter(this.filter); } }, deactivate: function() { this.removeStoreFilter(this.filter); }, getValue: function(field) { return field.getValue(); }, onFilterRemove: function() { if (!this.menu || this.active) { this.active = false; } } }); Ext.define('Ext.grid.filters.filter.Boolean', { extend: 'Ext.grid.filters.filter.SingleFilter', alias: 'grid.filter.boolean', type: 'boolean', operator: '=', defaultValue: false, yesText: 'Yes', noText: 'No', updateBuffer: 0, createMenu: function(config) { var me = this, gId = Ext.id(), listeners = { scope: me, click: me.onClick }, itemDefaults = me.getItemDefaults(); me.callParent(arguments); me.menu.add([ Ext.apply({ text: me.yesText, filterKey: 1, group: gId, checked: !!me.defaultValue, listeners: listeners }, itemDefaults), Ext.apply({ text: me.noText, filterKey: 0, group: gId, checked: !me.defaultValue, listeners: listeners }, itemDefaults) ]); }, onClick: function(field) { this.setValue(!!field.filterKey); }, setValue: function(value) { var me = this; me.filter.setValue(value); if (value !== undefined && me.active) { me.value = value; me.updateStoreFilter(); } else { me.setActive(true); } }, activateMenu: Ext.emptyFn }); Ext.define('Ext.grid.filters.filter.TriFilter', { extend: 'Ext.grid.filters.filter.Base', menuItems: [ 'lt', 'gt', '-', 'eq' ], constructor: function(config) { var me = this, stateful = false, filter = {}, filterGt, filterLt, filterEq, value, operator; me.callParent([ config ]); value = me.value; filterLt = me.getStoreFilter('lt'); filterGt = me.getStoreFilter('gt'); filterEq = me.getStoreFilter('eq'); if (filterLt || filterGt || filterEq) { stateful = me.active = true; if (filterLt) { me.onStateRestore(filterLt); } if (filterGt) { me.onStateRestore(filterGt); } if (filterEq) { me.onStateRestore(filterEq); } } else { if (me.grid.stateful && me.getGridStore().saveStatefulFilters) { value = undefined; } me.active = me.getActiveState(config, value); } filter.lt = filterLt || me.createFilter({ operator: 'lt', value: (!stateful && value && value.lt) || null }, 'lt'); filter.gt = filterGt || me.createFilter({ operator: 'gt', value: (!stateful && value && value.gt) || null }, 'gt'); filter.eq = filterEq || me.createFilter({ operator: 'eq', value: (!stateful && value && value.eq) || null }, 'eq'); me.filter = filter; if (me.active) { me.setColumnActive(true); if (!stateful) { for (operator in value) { me.addStoreFilter(me.filter[operator]); } } } }, activate: function(showingMenu) { var me = this, filters = me.filter, fields = me.fields, filter, field, operator, value, isRootMenuItem; if (me.preventFilterRemoval) { return; } for (operator in filters) { filter = filters[operator]; field = fields[operator]; value = filter.getValue(); if (value) { field.setValue(value); if (isRootMenuItem === undefined) { isRootMenuItem = me.owner.activeFilterMenuItem === field.up('menuitem'); } if (!isRootMenuItem) { field.up('menuitem').setChecked(true, true); } if (!showingMenu) { me.addStoreFilter(filter); } } } }, deactivate: function() { var me = this, filters = me.filter, f, filter; if (!me.countActiveFilters() || me.preventFilterRemoval) { return; } me.preventFilterRemoval = true; for (f in filters) { filter = filters[f]; if (filter.getValue()) { me.removeStoreFilter(filter); } } me.preventFilterRemoval = false; }, countActiveFilters: function() { var filters = this.filter, filterCollection = this.getGridStore().getFilters(), prefix = this.getBaseIdPrefix(), i = 0, filter; if (filterCollection.length) { for (filter in filters) { if (filterCollection.get(prefix + '-' + filter)) { i++; } } } return i; }, onFilterRemove: function(operator) { var me = this, value; if (!me.menu && me.countActiveFilters()) { me.active = false; } else if (me.menu) { value = {}; value[operator] = null; me.setValue(value); } }, onStateRestore: Ext.emptyFn, setValue: function(value) { var me = this, filters = me.filter, add = [], remove = [], active = false, filterCollection = me.getGridStore().getFilters(), field, filter, v, i, len, rLen, aLen; if (me.preventFilterRemoval) { return; } me.preventFilterRemoval = true; if ('eq' in value) { v = filters.lt.getValue(); if (v || v === 0) { remove.push(filters.lt); } v = filters.gt.getValue(); if (v || v === 0) { remove.push(filters.gt); } v = value.eq; if (v || v === 0) { add.push(filters.eq); filters.eq.setValue(v); } else { remove.push(filters.eq); } } else { v = filters.eq.getValue(); if (v || v === 0) { remove.push(filters.eq); } if ('lt' in value) { v = value.lt; if (v || v === 0) { add.push(filters.lt); filters.lt.setValue(v); } else { remove.push(filters.lt); } } if ('gt' in value) { v = value.gt; if (v || v === 0) { add.push(filters.gt); filters.gt.setValue(v); } else { remove.push(filters.gt); } } } rLen = remove.length; aLen = add.length; active = !!(me.countActiveFilters() + aLen - rLen); if (rLen || aLen || active !== me.active) { filterCollection.beginUpdate(); if (rLen) { for (i = 0; i < rLen; i++) { filter = remove[i]; me.fields[filter.getOperator()].setValue(null); filter.setValue(null); me.removeStoreFilter(filter); } } if (aLen) { for (i = 0; i < aLen; i++) { me.addStoreFilter(add[i]); } } me.setActive(active); filterCollection.endUpdate(); } me.preventFilterRemoval = false; } }); Ext.define('Ext.grid.filters.filter.Date', { extend: 'Ext.grid.filters.filter.TriFilter', alias: 'grid.filter.date', uses: [ 'Ext.picker.Date', 'Ext.menu.Menu' ], type: 'date', config: { fields: { lt: { text: 'Before' }, gt: { text: 'After' }, eq: { text: 'On' } }, pickerDefaults: { xtype: 'datepicker', border: 0 }, updateBuffer: 0, dateFormat: undefined }, itemDefaults: { xtype: 'menucheckitem', selectOnFocus: true, width: 125, menu: { layout: 'auto', plain: true } }, applyDateFormat: function(dateFormat) { return dateFormat || Ext.Date.defaultFormat; }, createMenu: function(config) { var me = this, listeners = { scope: me, checkchange: me.onCheckChange }, menuItems = me.menuItems, fields, itemDefaults, pickerCfg, i, len, key, item, cfg, field; me.callParent(arguments); itemDefaults = me.getItemDefaults(); fields = me.getFields(); pickerCfg = Ext.apply({ minDate: me.minDate, maxDate: me.maxDate, format: me.dateFormat, listeners: { scope: me, select: me.onMenuSelect } }, me.getPickerDefaults()); me.fields = {}; for (i = 0 , len = menuItems.length; i < len; i++) { key = menuItems[i]; if (key !== '-') { cfg = { menu: { items: [ Ext.apply({ itemId: key }, pickerCfg) ] } }; if (itemDefaults) { Ext.merge(cfg, itemDefaults); } if (fields) { Ext.merge(cfg, fields[key]); } item = me.menu.add(cfg); field = me.fields[key] = item.down('datepicker'); field.filter = me.filter[key]; field.filterKey = key; item.on(listeners); } else { me.menu.add(key); } } }, getPicker: function(item) { return this.fields[item]; }, onCheckChange: function(field, checked) { var filter = field.down('datepicker').filter, v; if (!checked && filter.getValue()) { v = {}; v[filter.getOperator()] = null; this.setValue(v); } }, onFilterRemove: function(operator) { var v = {}; v[operator] = null; this.setValue(v); this.fields[operator].up('menuitem').setChecked(false, true); }, onStateRestore: function(filter) { filter.setSerializer(this.getSerializer()); filter.setConvert(this.convertDateOnly); }, getFilterConfig: function(config, key) { config = this.callParent([ config, key ]); config.serializer = this.getSerializer(); config.convert = this.convertDateOnly; return config; }, convertDateOnly: function(v) { var result = null; if (v) { result = Ext.Date.clearTime(v, true).getTime(); } return result; }, getSerializer: function() { var me = this; return function(data) { var value = data.value; if (value) { data.value = Ext.Date.format(value, me.getDateFormat()); } }; }, onMenuSelect: function(picker, date) { var fields = this.fields, field = fields[picker.itemId], gt = fields.gt, lt = fields.lt, eq = fields.eq, v = {}; field.up('menuitem').setChecked(true, true); if (field === eq) { lt.up('menuitem').setChecked(false, true); gt.up('menuitem').setChecked(false, true); } else { eq.up('menuitem').setChecked(false, true); if (field === gt && (+lt.value < +date)) { lt.up('menuitem').setChecked(false, true); v.lt = null; } else if (field === lt && (+gt.value > +date)) { gt.up('menuitem').setChecked(false, true); v.gt = null; } } v[field.filterKey] = date; this.setValue(v); picker.up('menu').hide(); } }); Ext.define('Ext.grid.filters.filter.List', { extend: 'Ext.grid.filters.filter.SingleFilter', alias: 'grid.filter.list', type: 'list', operator: 'in', itemDefaults: { checked: false, hideOnClick: false }, idField: 'id', labelField: 'text', labelIndex: null, loadingText: 'Loading...', loadOnShow: true, single: false, plain: true, constructor: function(config) { var me = this, options, store; me.callParent([ config ]); if (me.itemDefaults.checked) { Ext.Error.raise('The itemDefaults.checked config is not supported, use the value config instead.'); } options = me.options; store = me.store; if (!options && !store) { me.getGridStore().on({ scope: me, add: me.onDataChanged, refresh: me.onDataChanged, remove: me.onDataChanged, update: me.onDataChanged }); } me.labelIndex = me.labelIndex || me.column.dataIndex; }, destroy: function() { var me = this, store = me.store, autoStore = me.autoStore; if (store) { if (autoStore || store.autoDestroy) { store.destroy(); } else { store.un('load', me.bindMenuStore, me); } me.store = null; } if (autoStore) { me.getGridStore().un({ scope: me, add: me.onDataChanged, refresh: me.onDataChanged, remove: me.onDataChanged, update: me.onDataChanged }); } me.callParent(); }, activateMenu: function() { var me = this, value = me.filter.getValue(), items, i, len, checkItem; if (!value || !value.length) { return; } items = me.menu.items; for (i = 0 , len = items.length; i < len; i++) { checkItem = items.getAt(i); if (Ext.Array.indexOf(value, checkItem.value) > -1) { checkItem.setChecked(true, true); } } }, bindMenuStore: function(options) { var me = this; if (me.grid.isDestroyed || me.preventFilterRemoval) { return; } me.createListStore(options); me.createMenuItems(me.store); me.loaded = true; }, createListStore: function(options) { var me = this, store = me.store, isStore = options.isStore, idField = me.idField, labelField = me.labelField, optionsStore = false, storeData, o, i, len, value; if (isStore) { if (options !== me.getGridStore()) { optionsStore = true; store = me.store = options; } else { me.autoStore = true; storeData = me.getOptionsFromStore(options); } } else { storeData = []; for (i = 0 , len = options.length; i < len; i++) { value = options[i]; switch (Ext.typeOf(value)) { case 'array': storeData.push(value); break; case 'object': storeData.push(value); break; default: if (value != null) { o = {}; o[idField] = value; o[labelField] = value; storeData.push(o); }; } } } if (!optionsStore) { if (store) { store.destroy(); } store = me.store = new Ext.data.Store({ fields: [ idField, labelField ], data: storeData }); me.loaded = true; } me.setStoreFilter(store); }, createMenu: function(config) { var me = this, gridStore = me.getGridStore(), store = me.store, options = me.options, menu; if (store) { me.store = store = Ext.StoreManager.lookup(store); } me.callParent([ config ]); menu = me.menu; if (store) { if (!store.getCount()) { menu.add({ text: me.loadingText, iconCls: Ext.baseCSSPrefix + 'mask-msg-text' }); menu.on('show', me.show, me); store.on('load', me.bindMenuStore, me, { single: true }); } else { me.createMenuItems(store); } } else if (options) { me.bindMenuStore(options); } else if (gridStore.getCount() || gridStore.data.filtered) { me.bindMenuStore(gridStore); } else { gridStore.on('load', me.bindMenuStore, me, { single: true }); } }, createMenuItems: function(store) { var me = this, menu = me.menu, len = store.getCount(), contains = Ext.Array.contains, listeners, itemDefaults, record, gid, idValue, idField, labelValue, labelField, i, item, processed; if (len && menu) { listeners = { checkchange: me.onCheckChange, scope: me }; itemDefaults = me.getItemDefaults(); menu.suspendLayouts(); menu.removeAll(true); gid = me.single ? Ext.id() : null; idField = me.idField; labelField = me.labelField; processed = []; for (i = 0; i < len; i++) { record = store.getAt(i); idValue = record.get(idField); labelValue = record.get(labelField); if (labelValue == null || contains(processed, idValue)) { continue; } processed.push(labelValue); item = menu.add(Ext.apply({ text: labelValue, group: gid, value: idValue, listeners: listeners }, itemDefaults)); } menu.resumeLayouts(true); } }, getFilterConfig: function(config, key) { config.value = config.value || []; return this.callParent([ config, key ]); }, getOptionsFromStore: function(store) { var me = this, data = store.getData(), map = {}, ret = [], dataIndex = me.dataIndex, labelIndex = me.labelIndex, items, i, length, recData, idValue, labelValue; if (store.isFiltered()) { data = data.getSource(); } items = data.items; length = items.length; for (i = 0; i < length; ++i) { recData = items[i].data; idValue = recData[dataIndex]; labelValue = recData[labelIndex]; if (labelValue === undefined) { labelValue = idValue; } if (!map[idValue]) { map[idValue] = 1; ret.push([ idValue, labelValue ]); } } return ret; }, onCheckChange: function() { var me = this, updateBuffer = me.updateBuffer; if (updateBuffer) { me.task.delay(updateBuffer, null, null); } else { me.setValue(); } }, onDataChanged: function(store) { if (!this.preventDefault) { this.bindMenuStore(store); } }, setStoreFilter: function(options) { var me = this, value = me.value, filter = me.filter; if (value) { if (!Ext.isArray(value)) { value = [ value ]; } filter.setValue(value); } if (me.active) { me.preventFilterRemoval = true; me.addStoreFilter(filter); me.preventFilterRemoval = false; } }, setValue: function() { var me = this, items = me.menu.items, value = [], i, len, checkItem; me.preventDefault = true; for (i = 0 , len = items.length; i < len; i++) { checkItem = items.getAt(i); if (checkItem.checked) { value.push(checkItem.value); } } me.filter.setValue(value); len = value.length; if (len && me.active) { me.updateStoreFilter(); } else { me.setActive(!!len); } me.preventDefault = false; }, show: function() { var store = this.store; if (this.loadOnShow && !this.loaded && !store.hasPendingLoad()) { store.load(); } } }); Ext.define('Ext.grid.filters.filter.Number', { extend: 'Ext.grid.filters.filter.TriFilter', alias: [ 'grid.filter.number', 'grid.filter.numeric' ], uses: [ 'Ext.form.field.Number' ], type: 'number', config: { fields: { gt: { iconCls: Ext.baseCSSPrefix + 'grid-filters-gt', margin: '0 0 3px 0' }, lt: { iconCls: Ext.baseCSSPrefix + 'grid-filters-lt', margin: '0 0 3px 0' }, eq: { iconCls: Ext.baseCSSPrefix + 'grid-filters-eq', margin: 0 } } }, emptyText: 'Enter Number...', itemDefaults: { xtype: 'numberfield', enableKeyEvents: true, hideEmptyLabel: false, labelSeparator: '', labelWidth: 29, selectOnFocus: false }, menuDefaults: { bodyPadding: 3, showSeparator: false }, createMenu: function() { var me = this, listeners = { scope: me, keyup: me.onValueChange, spin: { fn: me.onInputSpin, buffer: 200 }, el: { click: me.stopFn } }, itemDefaults = me.getItemDefaults(), menuItems = me.menuItems, fields = me.getFields(), field, i, len, key, item, cfg; me.callParent(); me.fields = {}; for (i = 0 , len = menuItems.length; i < len; i++) { key = menuItems[i]; if (key !== '-') { field = fields[key]; cfg = { labelClsExtra: Ext.baseCSSPrefix + 'grid-filters-icon ' + field.iconCls }; if (itemDefaults) { Ext.merge(cfg, itemDefaults); } Ext.merge(cfg, field); cfg.emptyText = cfg.emptyText || me.emptyText; delete cfg.iconCls; me.fields[key] = item = me.menu.add(cfg); item.filter = me.filter[key]; item.filterKey = key; item.on(listeners); } else { me.menu.add(key); } } }, getValue: function(field) { var value = {}; value[field.filterKey] = field.getValue(); return value; }, onInputSpin: function(field, direction) { var value = {}; value[field.filterKey] = field.getValue(); this.setValue(value); }, stopFn: function(e) { e.stopPropagation(); } }); Ext.define('Ext.grid.filters.filter.String', { extend: 'Ext.grid.filters.filter.SingleFilter', alias: 'grid.filter.string', type: 'string', operator: 'like', emptyText: 'Enter Filter Text...', itemDefaults: { xtype: 'textfield', enableKeyEvents: true, hideEmptyLabel: false, iconCls: Ext.baseCSSPrefix + 'grid-filters-find', labelSeparator: '', labelWidth: 29, margin: 0, selectOnFocus: true }, menuDefaults: { bodyPadding: 3, showSeparator: false }, createMenu: function() { var me = this, config; me.callParent(); config = Ext.apply({}, me.getItemDefaults()); if (config.iconCls && !('labelClsExtra' in config)) { config.labelClsExtra = Ext.baseCSSPrefix + 'grid-filters-icon ' + config.iconCls; } delete config.iconCls; config.emptyText = config.emptyText || me.emptyText; me.inputItem = me.menu.add(config); me.inputItem.on({ scope: me, keyup: me.onValueChange, el: { click: function(e) { e.stopPropagation(); } } }); }, setValue: function(value) { var me = this; if (me.inputItem) { me.inputItem.setValue(value); } me.filter.setValue(value); if (value && me.active) { me.value = value; me.updateStoreFilter(); } else { me.setActive(!!value); } }, activateMenu: function() { this.inputItem.setValue(this.filter.getValue()); } }); Ext.define('Ext.grid.filters.Filters', { extend: 'Ext.plugin.Abstract', requires: [ 'Ext.grid.filters.filter.*' ], mixins: [ 'Ext.util.StoreHolder' ], alias: 'plugin.gridfilters', pluginId: 'gridfilters', defaultFilterTypes: { 'boolean': 'boolean', 'int': 'number', date: 'date', number: 'number' }, filterCls: Ext.baseCSSPrefix + 'grid-filters-filtered-column', menuFilterText: 'Filters', showMenu: true, stateId: undefined, init: function(grid) { var me = this, store, headerCt; Ext.Assert.falsey(me.grid); me.grid = grid; grid.filters = me; if (me.grid.normalGrid) { me.isLocked = true; } grid.clearFilters = me.clearFilters.bind(me); store = grid.store; headerCt = grid.headerCt; headerCt.on({ scope: me, add: me.onAdd, menucreate: me.onMenuCreate }); grid.on({ scope: me, destroy: me.onGridDestroy, reconfigure: me.onReconfigure }); me.bindStore(store); if (grid.stateful) { store.statefulFilters = true; } me.initColumns(); }, initColumns: function() { var grid = this.grid, store = grid.getStore(), columns = grid.columnManager.getColumns(), len = columns.length, i, column, filter, filterCollection; for (i = 0; i < len; i++) { column = columns[i]; filter = column.filter; if (filter && !filter.isGridFilter) { if (!filterCollection) { filterCollection = store.getFilters(); filterCollection.beginUpdate(); } this.createColumnFilter(column); } } if (filterCollection) { filterCollection.endUpdate(); } }, createColumnFilter: function(column) { var me = this, columnFilter = column.filter, filter = { column: column, grid: me.grid, owner: me }, field, model, type; if (Ext.isString(columnFilter)) { filter.type = columnFilter; } else { Ext.apply(filter, columnFilter); } if (!filter.type) { model = me.store.getModel(); field = model && model.getField(column.dataIndex); type = field && field.type; filter.type = (type && me.defaultFilterTypes[type]) || column.defaultFilterType || 'string'; } column.filter = Ext.Factory.gridFilter(filter); }, onAdd: function(headerCt, column, index) { var filter = column.filter; if (filter && !filter.isGridFilter) { this.createColumnFilter(column); } }, onMenuCreate: function(headerCt, menu) { menu.on({ beforeshow: this.onMenuBeforeShow, scope: this }); }, onMenuBeforeShow: function(menu) { var me = this, menuItem, filter, parentTable, parentTableId; if (me.showMenu) { if (!me.filterMenuItem) { me.filterMenuItem = {}; } parentTable = menu.up('tablepanel'); parentTableId = parentTable.id; menuItem = me.filterMenuItem[parentTableId]; if (!menuItem || menuItem.isDestroyed) { menuItem = me.createMenuItem(menu, parentTableId); } me.activeFilterMenuItem = menuItem; filter = me.getMenuFilter(parentTable.headerCt); if (filter) { filter.showMenu(menuItem); } menuItem.setVisible(!!filter); me.sep.setVisible(!!filter); } }, createMenuItem: function(menu, parentTableId) { var me = this, item; me.sep = menu.add('-'); item = menu.add({ checked: false, itemId: 'filters', text: me.menuFilterText, listeners: { scope: me, checkchange: me.onCheckChange } }); return (me.filterMenuItem[parentTableId] = item); }, onGridDestroy: function() { var me = this, filterMenuItem = me.filterMenuItem, item; me.bindStore(null); me.sep = Ext.destroy(me.sep); for (item in filterMenuItem) { filterMenuItem[item].destroy(); } me.grid = null; }, onUnbindStore: function(store) { store.getFilters().un('remove', this.onFilterRemove, this); }, onBindStore: function(store, initial, propName) { this.local = !store.getRemoteFilter(); store.getFilters().on('remove', this.onFilterRemove, this); }, onFilterRemove: function(filterCollection, list) { var len = list.items.length, columnManager = this.grid.columnManager, i, item, header, filter; for (i = 0; i < len; i++) { item = list.items[i]; header = columnManager.getHeaderByDataIndex(item.getProperty()); if (header) { filter = header.filter; if (!filter || !filter.menu || item.getId().indexOf(filter.getBaseIdPrefix()) === -1) { continue; } if (!filter.preventFilterRemoval) { filter.onFilterRemove(item.getOperator()); } } } }, getMenuFilter: function(headerCt) { return headerCt.getMenu().activeHeader.filter; }, onCheckChange: function(item, value) { var parentTable = this.isLocked ? item.up('tablepanel') : this.grid, filter = this.getMenuFilter(parentTable.headerCt); filter.setActive(value); }, getHeaders: function() { return this.grid.view.headerCt.columnManager.getColumns(); }, isStateful: function() { return this.grid.stateful; }, addFilter: function(filters) { var me = this, grid = me.grid, store = me.store, hasNewColumns = false, suppressNextFilter = true, dataIndex, column, i, len, filter, columnFilter; if (!Ext.isArray(filters)) { filters = [ filters ]; } for (i = 0 , len = filters.length; i < len; i++) { filter = filters[i]; dataIndex = filter.dataIndex; column = grid.columnManager.getHeaderByDataIndex(dataIndex); if (column) { hasNewColumns = true; if (filter.value) { suppressNextFilter = false; } columnFilter = column.filter; if (columnFilter && columnFilter.isGridFilter) { columnFilter.deactivate(); columnFilter.destroy(); if (me.activeFilterMenuItem) { me.activeFilterMenuItem.menu = null; } } column.filter = filter; } } if (hasNewColumns) { store.suppressNextFilter = suppressNextFilter; me.initColumns(); store.suppressNextFilter = false; } }, addFilters: function(filters) { if (filters) { this.addFilter(filters); } }, clearFilters: function() { var grid = this.grid, columns = grid.columnManager.getColumns(), store = grid.store, column, filter, i, len, filterCollection; for (i = 0 , len = columns.length; i < len; i++) { column = columns[i]; filter = column.filter; if (filter && filter.isGridFilter) { if (!filterCollection) { filterCollection = store.getFilters(); filterCollection.beginUpdate(); } filter.setActive(false); } } if (filterCollection) { filterCollection.endUpdate(); } }, onReconfigure: function(grid, store, columns, oldStore) { var filterMenuItem = this.filterMenuItem, key; for (key in filterMenuItem) { filterMenuItem[key].setMenu(null); } if (store && oldStore !== store) { this.bindStore(store); } } }); Ext.define('Ext.grid.locking.HeaderContainer', { extend: 'Ext.grid.header.Container', requires: [ 'Ext.grid.ColumnManager' ], headerCtRelayEvents: [ "blur", "focus", "move", "resize", "destroy", "beforedestroy", "boxready", "afterrender", "render", "beforerender", "removed", "hide", "beforehide", "show", "beforeshow", "enable", "disable", "added", "deactivate", "beforedeactivate", "activate", "beforeactivate", "remove", "add", "beforeremove", "beforeadd", "afterlayout", "menucreate", "sortchange", "columnschanged", "columnshow", "columnhide", "columnmove", "headertriggerclick", "headercontextmenu", "headerclick", "columnresize", "statesave", "beforestatesave", "staterestore", "beforestaterestore" ], constructor: function(lockable) { var me = this, lockedGrid = lockable.lockedGrid, normalGrid = lockable.normalGrid; me.lockable = lockable; me.callParent(); lockedGrid.visibleColumnManager.rootColumns = normalGrid.visibleColumnManager.rootColumns = lockable.visibleColumnManager = me.visibleColumnManager = new Ext.grid.ColumnManager(true, lockedGrid.headerCt, normalGrid.headerCt); lockedGrid.columnManager.rootColumns = normalGrid.columnManager.rootColumns = lockable.columnManager = me.columnManager = new Ext.grid.ColumnManager(false, lockedGrid.headerCt, normalGrid.headerCt); me.relayEvents(lockedGrid.headerCt, me.headerCtRelayEvents); me.relayEvents(normalGrid.headerCt, me.headerCtRelayEvents); }, getRefItems: function() { return this.lockable.lockedGrid.headerCt.getRefItems().concat(this.lockable.normalGrid.headerCt.getRefItems()); }, getGridColumns: function() { return this.lockable.lockedGrid.headerCt.getGridColumns().concat(this.lockable.normalGrid.headerCt.getGridColumns()); }, getColumnsState: function() { var me = this, locked = me.lockable.lockedGrid.headerCt.getColumnsState(), normal = me.lockable.normalGrid.headerCt.getColumnsState(); return locked.concat(normal); }, applyColumnsState: function(columns) { var me = this, lockedGrid = me.lockable.lockedGrid, lockedHeaderCt = lockedGrid.headerCt, normalHeaderCt = me.lockable.normalGrid.headerCt, lockedCols = Ext.Array.toValueMap(lockedHeaderCt.items.items, 'stateId'), normalCols = Ext.Array.toValueMap(normalHeaderCt.items.items, 'stateId'), locked = [], normal = [], lockedWidth = 1, length = columns.length, i, existing, lockedDefault, col; for (i = 0; i < length; i++) { col = columns[i]; lockedDefault = lockedCols[col.id]; existing = lockedDefault || normalCols[col.id]; if (existing) { if (existing.applyColumnState) { existing.applyColumnState(col); } if (existing.locked === undefined) { existing.locked = !!lockedDefault; } if (existing.locked) { locked.push(existing); if (!existing.hidden && typeof existing.width === 'number') { lockedWidth += existing.width; } } else { normal.push(existing); } } } if (locked.length + normal.length === lockedHeaderCt.items.getCount() + normalHeaderCt.items.getCount()) { lockedHeaderCt.removeAll(false); normalHeaderCt.removeAll(false); lockedHeaderCt.add(locked); normalHeaderCt.add(normal); lockedGrid.setWidth(lockedWidth); } }, disable: function() { var topGrid = this.lockable; topGrid.lockedGrid.headerCt.disable(); topGrid.normalGrid.headerCt.disable(); }, enable: function() { var topGrid = this.lockable; topGrid.lockedGrid.headerCt.enable(); topGrid.normalGrid.headerCt.enable(); } }); Ext.define('Ext.grid.locking.View', { alternateClassName: 'Ext.grid.LockingView', requires: [ 'Ext.view.AbstractView', 'Ext.view.Table' ], mixins: [ 'Ext.util.Observable', 'Ext.util.StoreHolder', 'Ext.util.Focusable' ], isLockingView: true, loadMask: true, eventRelayRe: /^(beforeitem|beforecontainer|item|container|cell|refresh)/, constructor: function(config) { var me = this, lockedView, normalView; me.ownerGrid = config.ownerGrid; me.ownerGrid.view = me; me.navigationModel = config.locked.xtype === 'treepanel' ? new Ext.tree.NavigationModel(me) : new Ext.grid.NavigationModel(me); config.locked.viewConfig.bindStore = Ext.emptyFn; config.normal.viewConfig.bindStore = me.subViewBindStore; config.normal.viewConfig.isNormalView = config.locked.viewConfig.isLockedView = true; config.locked.viewConfig.beforeLayout = config.normal.viewConfig.beforeLayout = me.beforeLayout; config.locked.viewConfig.navigationModel = config.normal.viewConfig.navigationModel = me.navigationModel; me.lockedGrid = me.ownerGrid.lockedGrid = Ext.ComponentManager.create(config.locked); me.lockedView = lockedView = me.lockedGrid.getView(); if (me.ownerGrid.shrinkWrapLocked) { me.lockedGrid.width += (Ext.num(lockedView.getSelectionModel().headerWidth, 0) + (me.lockedGrid.getVisibleColumnManager().getColumns().length ? 1 : 0)); } me.selModel = config.normal.viewConfig.selModel = lockedView.getSelectionModel(); if (me.lockedGrid.isTree) { me.lockedView.animate = false; config.normal.store = lockedView.store; config.normal.viewConfig.stripeRows = me.lockedView.stripeRows; config.normal.rowLines = me.lockedGrid.rowLines; } me.normalGrid = me.ownerGrid.normalGrid = Ext.ComponentManager.create(config.normal); lockedView.lockingPartner = normalView = me.normalView = me.normalGrid.getView(); normalView.lockingPartner = lockedView; me.loadMask = (config.loadMask !== undefined) ? config.loadMask : me.loadMask; me.mixins.observable.constructor.call(me); me.relayEvents(lockedView, Ext.view.Table.events); me.relayEvents(normalView, Ext.view.Table.events); normalView.on({ scope: me, itemmouseleave: me.onItemMouseLeave, itemmouseenter: me.onItemMouseEnter }); lockedView.on({ scope: me, itemmouseleave: me.onItemMouseLeave, itemmouseenter: me.onItemMouseEnter }); me.ownerGrid.on({ render: me.onPanelRender, scope: me }); me.loadingText = normalView.loadingText; me.loadingCls = normalView.loadingCls; me.loadingUseMsg = normalView.loadingUseMsg; me.itemSelector = me.getItemSelector(); me.all = normalView.all; me.bindStore(normalView.dataSource, true, 'dataSource'); }, subViewBindStore: function(dataSource) { var me = this, selModel = me.getSelectionModel(); if (dataSource !== null && !me.ownerGrid.reconfiguring) { dataSource = me.store; } selModel.bindStore(dataSource); selModel.bindComponent(me); }, beforeLayout: function() { var me = this.ownerCt.ownerLockable.view, lockedView = me.lockedGrid.view, normalView = me.normalGrid.view; if (!me.relayingOperation) { if (me.lockedGrid.isVisible()) { if (lockedView.refreshNeeded) { lockedView.doFirstRefresh(lockedView.dataSource); } } if (normalView.refreshNeeded) { normalView.doFirstRefresh(normalView.dataSource); } } }, onPanelRender: function() { var me = this, mask = me.loadMask, cfg = { target: me.ownerGrid, msg: me.loadingText, msgCls: me.loadingCls, useMsg: me.loadingUseMsg, store: me.ownerGrid.store }; me.el = me.ownerGrid.getTargetEl(); me.rendered = true; me.initFocusableEvents(); me.fireEvent('render', me); if (mask) { if (Ext.isObject(mask)) { cfg = Ext.apply(cfg, mask); } me.loadMask = new Ext.LoadMask(cfg); } }, getRefOwner: function() { return this.ownerGrid; }, getVisibleColumnManager: function() { return this.ownerGrid.getVisibleColumnManager(); }, getTopLevelVisibleColumnManager: function() { return this.ownerGrid.getVisibleColumnManager(); }, getGridColumns: function() { return this.getVisibleColumnManager().getColumns(); }, getEl: function(column) { return this.getViewForColumn(column).getEl(); }, getCellSelector: function() { return this.normalView.getCellSelector(); }, getItemSelector: function() { return this.normalView.getItemSelector(); }, getViewForColumn: function(column) { var view = this.lockedView, inLocked; view.headerCt.cascade(function(col) { if (col === column) { inLocked = true; return false; } }); return inLocked ? view : this.normalView; }, onItemMouseEnter: function(view, record) { var me = this, locked = me.lockedView, other = me.normalView, item; if (view.trackOver) { if (view !== locked) { other = locked; } item = other.getNode(record); other.highlightItem(item); } }, onItemMouseLeave: function(view, record) { var me = this, locked = me.lockedView, other = me.normalView; if (view.trackOver) { if (view !== locked) { other = locked; } other.clearHighlight(); } }, relayFn: function(name, args) { args = args || []; var me = this, view = me.lockedView; me.relayingOperation = true; view[name].apply(view, args); view = me.normalView; view[name].apply(view, args); me.relayingOperation = false; }, getSelectionModel: function() { return this.normalView.getSelectionModel(); }, getNavigationModel: function() { return this.navigationModel; }, getStore: function() { return this.ownerGrid.store; }, onBindStore: function(store, initial, propName) { var me = this, lockedView = me.lockedView, normalView = me.normalView; if (normalView.componentLayoutCounter && !(lockedView.blockRefresh && normalView.blockRefresh)) { Ext.suspendLayouts(); lockedView.doFirstRefresh(store); normalView.doFirstRefresh(store); Ext.resumeLayouts(true); } }, getStoreListeners: function() { var me = this; return { refresh: me.onDataRefresh, replace: me.onReplace, add: me.onAdd, remove: me.onRemove, update: me.onUpdate, clear: me.refresh, beginupdate: me.onBeginUpdate, endupdate: me.onEndUpdate }; }, onBeginUpdate: function() { Ext.suspendLayouts(); this.relayFn('onBeginUpdate', arguments); Ext.resumeLayouts(true); }, onEndUpdate: function() { Ext.suspendLayouts(); this.relayFn('onEndUpdate', arguments); Ext.resumeLayouts(true); }, onDataRefresh: function() { Ext.suspendLayouts(); this.relayFn('onDataRefresh', arguments); Ext.resumeLayouts(true); }, onReplace: function() { Ext.suspendLayouts(); this.relayFn('onReplace', arguments); Ext.resumeLayouts(true); }, onAdd: function() { Ext.suspendLayouts(); this.relayFn('onAdd', arguments); Ext.resumeLayouts(true); }, onRemove: function() { Ext.suspendLayouts(); this.relayFn('onRemove', arguments); Ext.resumeLayouts(true); }, onUpdate: function() { var normalView = this.normalGrid.view; Ext.suspendLayouts(); this.relayFn('onUpdate', arguments); if (normalView.hasVariableRowHeight() && normalView.bufferedRenderer) { Ext.on({ afterlayout: normalView.bufferedRenderer.refreshSize, scope: normalView.bufferedRenderer, single: true }); } Ext.resumeLayouts(true); }, refresh: function() { Ext.suspendLayouts(); this.relayFn('refresh', arguments); Ext.resumeLayouts(true); }, getNode: function(nodeInfo) { return this.normalView.getNode(nodeInfo); }, getRow: function(nodeInfo) { return this.normalView.getRow(nodeInfo); }, getCell: function(record, column) { var view = this.getViewForColumn(column), row = view.getRow(record); return Ext.fly(row).down(column.getCellSelector()); }, indexOf: function(record) { var result = this.lockedView.indexOf(record); if (!result) { result = this.normalView.indexOf(record); } return result; }, focus: function() { var target = this.ownerGrid.down('>tablepanel:not(hidden)>tableview'); if (target) { target.focus(); } }, focusRow: function(row) { var view, lastFocused = this.getNavigationModel().lastFocused; view = lastFocused ? lastFocused.view : this.normalView; view.focusRow(row); }, focusCell: function(position) { position.view.focusCell(position); }, onRowFocus: function() { this.relayFn('onRowFocus', arguments); }, isVisible: function(deep) { return this.ownerGrid.isVisible(deep); }, getFocusEl: function() { var view, lastFocused = this.getNavigationModel().lastFocused; view = lastFocused ? lastFocused.view : this.normalView; return view.getFocusEl(); }, getCellInclusive: function(pos, returnDom) { var col = pos.column, lockedSize = this.lockedGrid.getColumnManager().getColumns().length; if (col >= lockedSize) { pos = Ext.apply({}, pos); pos.column -= lockedSize; return this.normalView.getCellInclusive(pos, returnDom); } else { return this.lockedView.getCellInclusive(pos, returnDom); } }, getHeaderByCell: function(cell) { if (cell) { return this.getVisibleColumnManager().getHeaderById(cell.getAttribute('data-columnId')); } return false; }, onRowSelect: function() { this.relayFn('onRowSelect', arguments); }, onRowDeselect: function() { this.relayFn('onRowDeselect', arguments); }, onCellSelect: function(cellContext) { cellContext.column.getView().onCellSelect({ record: cellContext.record, column: cellContext.column }); }, onCellDeselect: function(cellContext) { cellContext.column.getView().onCellDeselect({ record: cellContext.record, column: cellContext.column }); }, getCellByPosition: function(pos, returnDom) { var me = this, view = pos.view, col = pos.column; if (view === me) { view = col.getView(); } return view.getCellByPosition(pos, returnDom); }, getRecord: function(node) { var result = this.lockedView.getRecord(node); if (!result) { result = this.normalView.getRecord(node); } return result; }, scrollBy: function() { var normal = this.normalView; normal.scrollBy.apply(normal, arguments); }, ensureVisible: function() { var normal = this.normalView; normal.ensureVisible.apply(normal, arguments); }, disable: function() { this.relayFn('disable', arguments); }, enable: function() { this.relayFn('enable', arguments); }, addElListener: function() { this.relayFn('addElListener', arguments); }, refreshNode: function() { this.relayFn('refreshNode', arguments); }, addRowCls: function() { this.relayFn('addRowCls', arguments); }, removeRowCls: function() { this.relayFn('removeRowCls', arguments); }, destroy: function() { var me = this; me.bindStore(null, false, 'dataSource'); me.isDestroyed = true; me.clearListeners(); Ext.destroy(me.loadMask, me.navigationModel, me.selModel); } }, function() { this.borrow(Ext.Component, [ 'up' ]); this.borrow(Ext.view.AbstractView, [ 'doFirstRefresh', 'applyFirstRefresh' ]); this.borrow(Ext.view.Table, [ 'cellSelector', 'selectedCellCls', 'selectedItemCls' ]); }); Ext.define('Ext.grid.locking.Lockable', { alternateClassName: 'Ext.grid.Lockable', requires: [ 'Ext.grid.locking.View', 'Ext.grid.header.Container', 'Ext.grid.locking.HeaderContainer', 'Ext.view.Table' ], syncRowHeight: true, headerCounter: 0, scrollDelta: 40, lockedGridCls: Ext.baseCSSPrefix + 'grid-inner-locked', normalGridCls: Ext.baseCSSPrefix + 'grid-inner-normal', unlockText: 'Unlock', lockText: 'Lock', bothCfgCopy: [ 'invalidateScrollerOnRefresh', 'hideHeaders', 'enableColumnHide', 'enableColumnMove', 'enableColumnResize', 'sortableColumns', 'multiColumnSort', 'columnLines', 'rowLines', 'variableRowHeight', 'numFromEdge', 'trailingBufferZone', 'leadingBufferZone', 'scrollToLoadBuffer' ], normalCfgCopy: [ 'verticalScroller', 'verticalScrollDock', 'verticalScrollerType', 'scroll' ], lockedCfgCopy: [], determineXTypeToCreate: function(lockedSide) { var me = this, typeToCreate, xtypes, xtypesLn, xtype, superxtype; if (me.subGridXType) { typeToCreate = me.subGridXType; } else { if (!lockedSide) { return 'gridpanel'; } xtypes = this.getXTypes().split('/'); xtypesLn = xtypes.length; xtype = xtypes[xtypesLn - 1]; superxtype = xtypes[xtypesLn - 2]; if (superxtype !== 'tablepanel') { typeToCreate = superxtype; } else { typeToCreate = xtype; } } return typeToCreate; }, injectLockable: function() { this.focusable = false; this.lockable = true; this.hasView = true; var me = this, scrollbarSize = Ext.getScrollbarSize(), scrollbarWidth = scrollbarSize.width, store = me.store = Ext.StoreManager.lookup(me.store), lockedViewConfig = me.lockedViewConfig, normalViewConfig = me.normalViewConfig, Obj = Ext.Object, allFeatures, allPlugins, lockedGrid, normalGrid, i, columns, lockedHeaderCt, normalHeaderCt, listeners, viewConfig = me.viewConfig, loadMaskCfg = viewConfig && viewConfig.loadMask, loadMask = (loadMaskCfg !== undefined) ? loadMaskCfg : me.loadMask, bufferedRenderer = me.bufferedRenderer, clipVertLockedScrollbar = scrollbarWidth > 0 && Ext.supports.touchScroll !== 2; allFeatures = me.constructLockableFeatures(); me.features = null; allPlugins = me.constructLockablePlugins(); me.plugins = allPlugins.topPlugins; lockedGrid = { id: me.id + '-locked', isLocked: true, bufferedRenderer: bufferedRenderer, ownerGrid: me, ownerLockable: me, xtype: me.determineXTypeToCreate(true), store: store, reserveScrollbar: clipVertLockedScrollbar, scrollable: { indicators: { x: true, y: false } }, scrollerOwner: false, animate: false, border: false, cls: me.lockedGridCls, isLayoutRoot: function() { return this.floatedFromCollapse || me.normalGrid.floatedFromCollapse; }, features: allFeatures.lockedFeatures, plugins: allPlugins.lockedPlugins }; normalGrid = { id: me.id + '-normal', isLocked: false, bufferedRenderer: bufferedRenderer, ownerGrid: me, ownerLockable: me, xtype: me.determineXTypeToCreate(), store: store, reserveScrollbar: me.reserveScrollbar, scrollerOwner: false, border: false, cls: me.normalGridCls, isLayoutRoot: function() { return this.floatedFromCollapse || me.lockedGrid.floatedFromCollapse; }, features: allFeatures.normalFeatures, plugins: allPlugins.normalPlugins }; me.addCls(Ext.baseCSSPrefix + 'grid-locked'); Ext.copyTo(normalGrid, me, me.bothCfgCopy, true); Ext.copyTo(lockedGrid, me, me.bothCfgCopy, true); Ext.copyTo(normalGrid, me, me.normalCfgCopy, true); Ext.copyTo(lockedGrid, me, me.lockedCfgCopy, true); Ext.apply(normalGrid, me.normalGridConfig); Ext.apply(lockedGrid, me.lockedGridConfig); for (i = 0; i < me.normalCfgCopy.length; i++) { delete me[me.normalCfgCopy[i]]; } for (i = 0; i < me.lockedCfgCopy.length; i++) { delete me[me.lockedCfgCopy[i]]; } me.addStateEvents([ 'lockcolumn', 'unlockcolumn' ]); columns = me.processColumns(me.columns || [], lockedGrid); lockedGrid.columns = columns.locked; if (!lockedGrid.columns.items.length) { lockedGrid.hidden = true; } normalGrid.columns = columns.normal; if (!normalGrid.columns.items.length) { normalGrid.hidden = true; } normalGrid.flex = 1; lockedGrid.viewConfig = lockedViewConfig = (lockedViewConfig ? Obj.chain(lockedViewConfig) : {}); normalGrid.viewConfig = normalViewConfig = (normalViewConfig ? Obj.chain(normalViewConfig) : {}); lockedViewConfig.loadingUseMsg = false; lockedViewConfig.loadMask = false; if (clipVertLockedScrollbar) { lockedViewConfig.margin = '0 -' + scrollbarWidth + ' 0 0'; } normalViewConfig.loadMask = false; if (viewConfig && viewConfig.id) { Ext.log.warn('id specified on Lockable viewConfig, it will be shared between both views: "' + viewConfig.id + '"'); } Ext.applyIf(lockedViewConfig, viewConfig); Ext.applyIf(normalViewConfig, viewConfig); if (!me.initialConfig.layout) { me.layout = { type: 'hbox', align: 'stretch' }; } me.getLayout(); if (me.layout.type === 'border') { if (me.split) { lockedGrid.split = true; } if (!lockedGrid.region) { lockedGrid.region = 'west'; } if (!normalGrid.region) { normalGrid.region = 'center'; } me.addCls(Ext.baseCSSPrefix + 'grid-locked-split'); } if (!(me.layout instanceof Ext.layout.container.Box)) { me.split = false; } me.view = new Ext.grid.locking.View({ loadMask: loadMask, locked: lockedGrid, normal: normalGrid, ownerGrid: me }); lockedGrid = me.lockedGrid; normalGrid = me.normalGrid; normalGrid.getView().getScrollable().addPartner(lockedGrid.getView().getScrollable(), 'y'); if (scrollbarSize.height && Ext.supports.touchScroll !== 2) { lockedGrid.on({ afterlayout: me.afterLockedViewLayout, scope: me }); lockedGrid.getView().getOverflowStyle(); } lockedHeaderCt = lockedGrid.headerCt; normalHeaderCt = normalGrid.headerCt; if (clipVertLockedScrollbar) { lockedHeaderCt.reserveScrollbar = false; } me.headerCt = me.view.headerCt = new Ext.grid.locking.HeaderContainer(me); lockedHeaderCt.lockedCt = true; lockedHeaderCt.lockableInjected = true; normalHeaderCt.lockableInjected = true; lockedHeaderCt.on({ add: me.delaySyncLockedWidth, remove: me.delaySyncLockedWidth, columnshow: me.delaySyncLockedWidth, columnhide: me.delaySyncLockedWidth, sortchange: me.onLockedHeaderSortChange, columnresize: me.delaySyncLockedWidth, scope: me }); normalHeaderCt.on({ add: me.delaySyncLockedWidth, remove: me.delaySyncLockedWidth, columnshow: me.delaySyncLockedWidth, columnhide: me.delaySyncLockedWidth, sortchange: me.onNormalHeaderSortChange, scope: me }); me.modifyHeaderCt(); me.items = [ lockedGrid ]; if (me.split) { me.addCls(Ext.baseCSSPrefix + 'grid-locked-split'); me.items[1] = { xtype: 'splitter' }; } me.items.push(normalGrid); me.relayHeaderCtEvents(lockedHeaderCt); me.relayHeaderCtEvents(normalHeaderCt); me.storeRelayers = me.relayEvents(store, [ 'filterchange', 'groupchange' ]); me.gridRelayers = me.relayEvents(normalGrid, [ 'viewready' ]); }, getLockingViewConfig: function() { return { xclass: 'Ext.grid.locking.View', locked: this.lockedGrid, normal: this.normalGrid, panel: this }; }, processColumns: function(columns, lockedGrid) { var me = this, i, len, column, cp = new Ext.grid.header.Container(), lockedHeaders = [], normalHeaders = [], lockedHeaderCt = { itemId: 'lockedHeaderCt', stretchMaxPartner: '^^>>#normalHeaderCt', items: lockedHeaders }, normalHeaderCt = { itemId: 'normalHeaderCt', stretchMaxPartner: '^^>>#lockedHeaderCt', items: normalHeaders }, result = { lockedWidth: lockedGrid.width || 0, locked: lockedHeaderCt, normal: normalHeaderCt }, shrinkWrapLocked = !(lockedGrid.width || lockedGrid.flex), copy; if (!me.hasOwnProperty('shrinkWrapLocked')) { me.shrinkWrapLocked = shrinkWrapLocked; } if (Ext.isObject(columns)) { Ext.applyIf(lockedHeaderCt, columns); Ext.applyIf(normalHeaderCt, columns); copy = Ext.apply({}, columns); delete copy.items; Ext.apply(cp, copy); columns = columns.items; } cp.constructing = true; for (i = 0 , len = columns.length; i < len; ++i) { column = columns[i]; if (!column.isComponent) { column = cp.applyDefaults(column); column.initOwnerCt = cp; column = cp.lookupComponent(column); delete column.initOwnerCt; } column.processed = true; if (column.locked || column.autoLock) { if (shrinkWrapLocked && !column.hidden) { result.lockedWidth += me.getColumnWidth(column) || cp.defaultWidth; } lockedHeaders.push(column); } else { normalHeaders.push(column); } if (!column.headerId) { column.headerId = (column.initialConfig || column).id || ('h' + (++me.headerCounter)); } } me.fireEvent('processcolumns', me, lockedHeaders, normalHeaders); cp.destroy(); if (shrinkWrapLocked) { lockedGrid.width = result.lockedWidth; } return result; }, getColumnWidth: function(column) { var result = column.width || 0, subcols, len, i; if (column.flex) { Ext.Error.raise("Locked columns in an unsized locked side do NOT support a flex width. You must set a width on the " + column.text + "column."); } if (!result && column.isGroupHeader) { subcols = column.items.items; len = subcols.length; for (i = 0; i < len; i++) { result += this.getColumnWidth(subcols[i]); } } return result; }, afterLockedViewLayout: function() { var me = this, lockedGrid = me.lockedGrid, normalGrid = me.normalGrid, lockedView = lockedGrid.getView(), normalView = normalGrid.getView(), spacerHeight = Ext.getScrollbarSize().height, lockedViewHorizScrollBar = (lockedView.scrollFlags.x && lockedGrid.headerCt.tooNarrow ? spacerHeight : 0), normalViewHorizScrollBar = (normalView.scrollFlags.x && normalGrid.headerCt.tooNarrow ? spacerHeight : 0), normalScroller = normalView.getScrollable(), lockedScroller = lockedView.getScrollable(); if (lockedViewHorizScrollBar !== normalViewHorizScrollBar) { if (lockedViewHorizScrollBar) { normalScroller.setX('scroll'); lockedScroller.setX(true); } else { lockedScroller.setX('scroll'); normalScroller.setX(true); } } else { lockedScroller.setX(normalViewHorizScrollBar ? 'scroll' : true); normalScroller.setX(true); } }, ensureLockedVisible: function() { this.lockedGrid.ensureVisible.apply(this.lockedGrid, arguments); this.normalGrid.ensureVisible.apply(this.normalGrid, arguments); }, onLockedViewMouseWheel: function(e) { var me = this, deltaY = -me.scrollDelta * e.getWheelDeltas().y, lockedView = me.lockedGrid.getView(), lockedViewElDom = lockedView.el.dom, scrollTop, verticalCanScrollDown, verticalCanScrollUp; if (!me.ignoreMousewheel) { if (lockedViewElDom) { scrollTop = lockedView.getScrollY(); verticalCanScrollDown = scrollTop !== lockedViewElDom.scrollHeight - lockedViewElDom.clientHeight; verticalCanScrollUp = scrollTop !== 0; } if ((deltaY < 0 && verticalCanScrollUp) || (deltaY > 0 && verticalCanScrollDown)) { e.stopEvent(); scrollTop += deltaY; lockedView.setScrollY(scrollTop); me.normalGrid.getView().setScrollY(scrollTop); me.onNormalViewScroll(); } } }, onLockedViewScroll: function() { var me = this, lockedView = me.lockedGrid.getView(), normalView = me.normalGrid.getView(), lockedScrollTop = lockedView.getScrollY(), normalScrollTop = normalView.getScrollY(), normalTable, lockedTable; if (normalScrollTop !== lockedScrollTop) { normalView.setScrollY(lockedScrollTop); if (normalView.bufferedRenderer) { lockedTable = lockedView.body.dom; normalTable = normalView.body.dom; normalTable.style.position = 'absolute'; normalTable.style.top = lockedTable.style.top; } } }, onNormalViewScroll: function() { var me = this, lockedView = me.lockedGrid.getView(), normalView = me.normalGrid.getView(), lockedScrollTop = lockedView.getScrollY(), normalScrollTop = normalView.getScrollY(), lockedRowContainer; if (normalScrollTop !== lockedScrollTop) { lockedView.setScrollY(normalScrollTop); if (normalView.bufferedRenderer) { lockedRowContainer = lockedView.body; if (lockedRowContainer.dom) { lockedRowContainer.dom.style.position = 'absolute'; lockedRowContainer.translate(null, normalView.bufferedRenderer.bodyTop); } } } }, syncRowHeights: function() { if (!this.isDestroyed) { var me = this, normalView = me.normalGrid.getView(), lockedView = me.lockedGrid.getView(), normalSync = normalView.syncRowHeightBegin(), lockedSync = lockedView.syncRowHeightBegin(), scrollTop; normalView.syncRowHeightMeasure(normalSync); lockedView.syncRowHeightMeasure(lockedSync); normalView.syncRowHeightFinish(normalSync, lockedSync); lockedView.syncRowHeightFinish(lockedSync, normalSync); scrollTop = normalView.getScrollY(); lockedView.setScrollY(scrollTop); } }, modifyHeaderCt: function() { var me = this; me.lockedGrid.headerCt.getMenuItems = me.getMenuItems(me.lockedGrid.headerCt.getMenuItems, true); me.normalGrid.headerCt.getMenuItems = me.getMenuItems(me.normalGrid.headerCt.getMenuItems, false); me.lockedGrid.headerCt.showMenuBy = Ext.Function.createInterceptor(me.lockedGrid.headerCt.showMenuBy, me.showMenuBy); me.normalGrid.headerCt.showMenuBy = Ext.Function.createInterceptor(me.normalGrid.headerCt.showMenuBy, me.showMenuBy); }, onUnlockMenuClick: function() { this.unlock(); }, onLockMenuClick: function() { this.lock(); }, showMenuBy: function(clickEvent, t, header) { var menu = this.getMenu(), unlockItem = menu.down('#unlockItem'), lockItem = menu.down('#lockItem'), sep = unlockItem.prev(); if (header.lockable === false) { sep.hide(); unlockItem.hide(); lockItem.hide(); } else { sep.show(); unlockItem.show(); lockItem.show(); if (!unlockItem.initialConfig.disabled) { unlockItem.setDisabled(header.lockable === false); } if (!lockItem.initialConfig.disabled) { lockItem.setDisabled(!header.isLockable()); } } }, getMenuItems: function(getMenuItems, locked) { var me = this, unlockText = me.unlockText, lockText = me.lockText, unlockCls = Ext.baseCSSPrefix + 'hmenu-unlock', lockCls = Ext.baseCSSPrefix + 'hmenu-lock', unlockHandler = me.onUnlockMenuClick.bind(me), lockHandler = me.onLockMenuClick.bind(me); return function() { var o = getMenuItems.call(this); o.push('-', { itemId: 'unlockItem', iconCls: unlockCls, text: unlockText, handler: unlockHandler, disabled: !locked }); o.push({ itemId: 'lockItem', iconCls: lockCls, text: lockText, handler: lockHandler, disabled: locked }); return o; }; }, syncTaskDelay: 1, delaySyncLockedWidth: function() { var me = this, task = me.syncLockedWidthTask; if (!task) { task = me.syncLockedWidthTask = new Ext.util.DelayedTask(me.syncLockedWidth, me); } if (me.syncTaskDelay === 0) { me.syncLockedWidth(); } else { task.delay(1); } }, syncLockedWidth: function() { var me = this, rendered = me.rendered, locked = me.lockedGrid, lockedView = locked.view, normal = me.normalGrid, lockedColCount = locked.getVisibleColumnManager().getColumns().length, normalColCount = normal.getVisibleColumnManager().getColumns().length, task = me.syncLockedWidthTask; if (task) { task.cancel(); } Ext.suspendLayouts(); if (normalColCount) { normal.show(); if (lockedColCount) { if (rendered && me.shrinkWrapLocked && !locked.headerCt.forceFit) { delete locked.flex; locked.setWidth(locked.headerCt.getTableWidth() + locked.el.getBorderWidth('lr')); } locked.addCls(me.lockedGridCls); locked.show(); if (me.split) { me.child('splitter').show(); } } else { if (rendered) { locked.getView().clearViewEl(true); } locked.hide(); if (me.split) { me.child('splitter').hide(); } } if (Ext.supports.touchScroll !== 2 && Ext.Component.pendingLayouts) { lockedView.getScrollable().setX(true); } if (rendered) { me.ignoreMousewheel = lockedView.scrollFlags.y; } } else { normal.hide(); if (rendered) { lockedView.getEl().setStyle('border-bottom-width', '0'); } locked.flex = 1; delete locked.width; locked.removeCls(me.lockedGridCls); locked.show(); me.ignoreMousewheel = true; } Ext.resumeLayouts(true); return [ lockedColCount, normalColCount ]; }, onLockedHeaderSortChange: Ext.emptyFn, onNormalHeaderSortChange: Ext.emptyFn, lock: function(activeHd, toIdx, toCt) { var me = this, normalGrid = me.normalGrid, lockedGrid = me.lockedGrid, normalView = normalGrid.view, lockedView = lockedGrid.view, normalHCt = normalGrid.headerCt, refreshFlags, ownerCt, hadFocus; activeHd = activeHd || normalHCt.getMenu().activeHeader; hadFocus = activeHd.hasFocus; toCt = toCt || lockedGrid.headerCt; ownerCt = activeHd.ownerCt; if (!activeHd.isLockable()) { return; } if (activeHd.flex) { activeHd.width = activeHd.getWidth(); activeHd.flex = null; } Ext.suspendLayouts(); if (lockedGrid.hidden) { lockedGrid.show(); } normalView.blockRefresh = lockedView.blockRefresh = true; ownerCt.remove(activeHd, false); activeHd.locked = true; if (Ext.isDefined(toIdx)) { toCt.insert(toIdx, activeHd); } else { toCt.add(activeHd); } normalView.blockRefresh = lockedView.blockRefresh = false; refreshFlags = me.syncLockedWidth(); if (refreshFlags[0]) { lockedGrid.getView().refreshView(); } if (refreshFlags[1]) { normalGrid.getView().refreshView(); } Ext.resumeLayouts(true); if (hadFocus) { activeHd.focus(); } me.fireEvent('lockcolumn', me, activeHd); }, unlock: function(activeHd, toIdx, toCt) { var me = this, normalGrid = me.normalGrid, lockedGrid = me.lockedGrid, normalView = normalGrid.view, lockedView = lockedGrid.view, lockedHCt = lockedGrid.headerCt, refreshFlags, hadFocus; if (!Ext.isDefined(toIdx)) { toIdx = 0; } activeHd = activeHd || lockedHCt.getMenu().activeHeader; hadFocus = activeHd.hasFocus; toCt = toCt || normalGrid.headerCt; Ext.suspendLayouts(); normalView.blockRefresh = lockedView.blockRefresh = true; activeHd.ownerCt.remove(activeHd, false); activeHd.locked = false; toCt.insert(toIdx, activeHd); normalView.blockRefresh = lockedView.blockRefresh = false; refreshFlags = me.syncLockedWidth(); if (refreshFlags[0]) { lockedGrid.getView().refreshView(); } if (refreshFlags[1]) { normalGrid.getView().refreshView(); } Ext.resumeLayouts(true); if (hadFocus) { activeHd.focus(); } me.fireEvent('unlockcolumn', me, activeHd); }, reconfigureLockable: function(store, columns) { var me = this, oldStore = me.store, lockedGrid = me.lockedGrid, normalGrid = me.normalGrid, view; if (store && store !== oldStore) { store = Ext.data.StoreManager.lookup(store); me.store = store; lockedGrid.view.blockRefresh = normalGrid.view.blockRefresh = true; lockedGrid.bindStore(store); view = lockedGrid.view; view.store = store; if (!view.dataSource.isFeatureStore) { view.dataSource = store; } if (view.bufferedRenderer) { view.bufferedRenderer.bindStore(store); } normalGrid.bindStore(store); view = normalGrid.view; view.store = store; if (!view.dataSource.isFeatureStore) { view.dataSource = store; } if (view.bufferedRenderer) { view.bufferedRenderer.bindStore(store); } me.view.store = store; me.view.bindStore(normalGrid.view.dataSource, false, 'dataSource'); lockedGrid.view.blockRefresh = normalGrid.view.blockRefresh = false; } if (columns) { lockedGrid.reconfiguring = normalGrid.reconfiguring = true; lockedGrid.headerCt.removeAll(); normalGrid.headerCt.removeAll(); columns = me.processColumns(columns, lockedGrid); lockedGrid.headerCt.add(columns.locked.items); normalGrid.headerCt.add(columns.normal.items); lockedGrid.reconfiguring = normalGrid.reconfiguring = false; me.syncLockedWidth(); } me.refreshCounter = lockedGrid.view.refreshCounter; }, afterReconfigureLockable: function() { var lockedView = this.lockedGrid.getView(); if (this.refreshCounter === lockedView.refreshCounter) { this.view.refresh(); } }, constructLockableFeatures: function() { var features = this.features, feature, featureClone, lockedFeatures, normalFeatures, i = 0, len; if (features) { if (!Ext.isArray(features)) { features = [ features ]; } lockedFeatures = []; normalFeatures = []; len = features.length; for (; i < len; i++) { feature = features[i]; if (!feature.isFeature) { feature = Ext.create('feature.' + feature.ftype, feature); } switch (feature.lockableScope) { case 'locked': lockedFeatures.push(feature); break; case 'normal': normalFeatures.push(feature); break; default: feature.lockableScope = 'both'; lockedFeatures.push(feature); normalFeatures.push(featureClone = feature.clone()); featureClone.lockingPartner = feature; feature.lockingPartner = featureClone; } } } return { normalFeatures: normalFeatures, lockedFeatures: lockedFeatures }; }, constructLockablePlugins: function() { var plugins = this.plugins, plugin, normalPlugin, lockedPlugin, topPlugins, lockedPlugins, normalPlugins, i = 0, len, lockableScope, pluginCls; if (plugins) { if (!Ext.isArray(plugins)) { plugins = [ plugins ]; } topPlugins = []; lockedPlugins = []; normalPlugins = []; len = plugins.length; for (; i < len; i++) { plugin = plugins[i]; if (plugin.init) { lockableScope = plugin.lockableScope; } else { pluginCls = plugin.ptype ? Ext.ClassManager.getByAlias(('plugin.' + plugin.ptype)) : Ext.ClassManager.get(plugin.xclass); lockableScope = pluginCls.prototype.lockableScope; } switch (lockableScope) { case 'both': lockedPlugins.push(lockedPlugin = plugin.clonePlugin()); normalPlugins.push(normalPlugin = plugin.clonePlugin()); lockedPlugin.lockingPartner = normalPlugin; normalPlugin.lockingPartner = lockedPlugin; Ext.destroy(plugin); break; case 'locked': lockedPlugins.push(plugin); break; case 'normal': normalPlugins.push(plugin); break; default: topPlugins.push(plugin); } } } return { topPlugins: topPlugins, normalPlugins: normalPlugins, lockedPlugins: lockedPlugins }; }, destroyLockable: function() { var me = this, task = me.syncLockedWidthTask; if (task) { task.cancel(); me.syncLockedWidthTask = null; } Ext.destroy(me.view, me.headerCt); } }, function() { this.borrow(Ext.Component, [ 'constructPlugin' ]); }); Ext.define('Ext.grid.plugin.BufferedRenderer', { extend: 'Ext.AbstractPlugin', alias: 'plugin.bufferedrenderer', isBufferedRenderer: true, lockableScope: 'both', numFromEdge: 2, trailingBufferZone: 10, leadingBufferZone: 20, synchronousRender: true, scrollToLoadBuffer: 200, viewSize: 100, rowHeight: 21, position: 0, lastScrollDirection: 1, bodyTop: 0, scrollHeight: 0, loadId: 0, init: function(grid) { var me = this, view = grid.view, viewListeners = { scroll: me.onViewScroll, resize: me.onViewResize, refresh: me.onViewRefresh, columnschanged: me.checkVariableRowHeight, boxready: me.onViewBoxReady, scope: me, destroyable: true }, initialConfig = view.initialConfig; if (grid.isTree || (grid.ownerLockable && grid.ownerLockable.isTree)) { view.blockRefresh = false; if (initialConfig && initialConfig.loadMask === undefined) { view.loadMask = true; } } if (view.positionBody) { viewListeners.refresh = me.onViewRefresh; } me.grid = grid; me.view = view; me.isRTL = view.getInherited().rtl; view.bufferedRenderer = me; view.preserveScrollOnRefresh = true; view.animate = false; me.bindStore(view.dataSource); if (view.hasOwnProperty('rowHeight')) { me.rowHeight = view.rowHeight; } me.position = 0; me.gridListeners = grid.on({ reconfigure: 'onReconfigure', scope: me, destroyable: true }); me.viewListeners = view.on(viewListeners); }, checkVariableRowHeight: function() { var me = this, grid = me.grid; me.variableRowHeight = me.view.hasVariableRowHeight(); if (grid.ownerLockable) { grid.ownerLockable.syncRowHeight = me.variableRowHeight; } }, bindStore: function(store) { var me = this, view = me.view, dataSource = view.dataSource, hasFeatureStore = dataSource && dataSource.isFeatureStore; if (hasFeatureStore === store.isFeatureStore) { if (me.store) { me.unbindStore(); } me.storeListeners = store.on({ scope: me, groupchange: me.onStoreGroupChange, clear: me.onStoreClear, beforeload: me.onBeforeStoreLoad, load: me.onStoreLoad, destroyable: true }); me.store = store; } if (me.view.componentLayout.layoutCount) { delete me.viewSize; if (store.isBufferedStore) { store.setViewSize(me.viewSize); } me.onViewResize(me.view, 0, me.view.getHeight()); } }, onReconfigure: function(grid, store) { if (store && store !== this.store) { this.bindStore(store); } }, unbindStore: function() { this.storeListeners.destroy(); this.store = null; }, onBeforeStoreLoad: function() { var view = this.view; if (view && view.rendered) { view.el.dom.style.pointerEvents = 'none'; } this.disable(); }, onStoreLoad: function() { var view = this.view; if (view && view.rendered) { view.el.dom.style.pointerEvents = ''; } this.enable(); }, onStoreClear: function() { var me = this, view = me.view; if (view.rendered && !me.store.isDestroyed) { if (me.scrollTop !== 0) { me.bodyTop = me.scrollTop = me.position = me.scrollHeight = 0; me.view.setScrollY(0); } me.lastScrollDirection = me.scrollOffset = null; if (!view.hasOwnProperty('rowHeight')) { delete me.rowHeight; } } }, onStoreGroupChange: function(store) { this.refreshSize(); }, onViewBoxReady: function(view) { this.refreshScroller(view, this.scrollHeight); }, onViewRefresh: function(view, records) { var me = this, rows = view.all, height; me.checkVariableRowHeight(); if (!view.componentLayoutCounter && (view.headerCt.down('{flex}') || me.variableRowHeight)) { view.on({ boxready: Ext.Function.pass(me.onViewRefresh, [ view, records ], me), single: true }); return; } if (!view.hasOwnProperty('rowHeight') && rows.getCount()) { delete me.rowHeight; } me.refreshSize(); if (me.refreshing) { return; } if (me.scrollTop !== view.getScrollY()) { me.onViewScroll(); } else { if (!me.hasOwnProperty('bodyTop')) { me.bodyTop = rows.startIndex * me.rowHeight; view.setScrollY(me.bodyTop); } me.setBodyTop(me.bodyTop); height = view.getHeight(); if (rows.getCount() && height > 0) { me.onViewResize(view, null, height); if (records && (rows.getCount() !== records.length)) { records.length = 0; records.push.apply(records, me.store.getRange(rows.startIndex, rows.endIndex)); } } } }, refreshSize: function() { var me = this, view = me.view, nodeCache = view.all, newScrollHeight = me.getScrollHeight(); if (nodeCache.count && nodeCache.endIndex === (me.store.getCount()) - 1) { newScrollHeight = me.scrollHeight = me.bodyTop + view.body.dom.offsetHeight; } else if (newScrollHeight !== me.scrollHeight) { me.scrollHeight = newScrollHeight; } me.stretchView(view, newScrollHeight); }, onViewResize: function(view, width, height, oldWidth, oldHeight) { var me = this, newViewSize; if (!oldHeight || height !== oldHeight) { newViewSize = Math.ceil(height / me.rowHeight) + me.trailingBufferZone + me.leadingBufferZone; me.viewSize = me.setViewSize(newViewSize); me.viewClientHeight = view.el.dom.clientHeight; } if (view.touchScroll === 2) { view.getScrollable().setElementSize(null); } }, onWrappedColumnWidthChange: function(oldWidth, newWidth) { var me = this, view = me.view; if (me.store.getCount() && me.bodyTop) { me.refreshSize(); me.setViewSize(Math.ceil(view.getHeight() / me.rowHeight) + me.trailingBufferZone + me.leadingBufferZone); if (me.viewSize >= me.store.getCount()) { me.setBodyTop(0); } else if (newWidth > oldWidth && me.bodyTop + view.body.dom.offsetHeight - 1 > me.scrollHeight) { me.setBodyTop(Math.max(0, me.scrollHeight - view.body.dom.offsetHeight)); } else if (me.bodyTop > me.scrollTop || me.bodyTop + view.body.dom.offsetHeight < me.scrollTop + view.getHeight(true)) { me.setBodyTop(me.scrollTop - me.trailingBufferZone * me.rowHeight); } } }, stretchView: function(view, scrollRange) { var me = this, recordCount = me.store.getCount(), el, stretcherSpec; if (me.scrollTop > scrollRange) { me.position = me.scrollTop = scrollRange - view.body.dom.offsetHeight; view.setScrollY(me.scrollTop); } if (me.bodyTop > scrollRange) { view.body.translate(null, me.bodyTop = me.position); } if (view.touchScroll) { if (view.getScrollable()) { me.refreshScroller(view, scrollRange); } else if (!me.pendingScrollerRefresh) { view.on({ boxready: function() { me.refreshScroller(view, scrollRange); me.pendingScrollerRefresh = false; }, single: true }); me.pendingScrollerRefresh = true; } } if (!Ext.supports.touchScroll || Ext.supports.touchScroll === 1) { if (!me.stretcher) { el = view.getTargetEl(); if (view.refreshCounter) { view.fixedNodes++; } stretcherSpec = { role: 'presentation', style: { width: '1px', height: '1px', 'marginTop': (scrollRange - 1) + 'px', position: 'absolute' } }; stretcherSpec.style[me.isRTL ? 'right' : 'left'] = 0; me.stretcher = el.createChild(stretcherSpec, el.dom.firstChild); } if (me.hasOwnProperty('viewSize') && recordCount <= me.viewSize) { me.stretcher.dom.style.display = 'none'; } else { me.stretcher.dom.style.marginTop = (scrollRange - 1) + 'px'; me.stretcher.dom.style.display = ''; } } }, refreshScroller: function(view, scrollRange) { var scroller = view.getScrollable(); if (scroller) { scroller.setSize({ x: view.headerCt.getTableWidth(), y: scrollRange }); } }, setViewSize: function(viewSize, fromLockingPartner) { var me = this, store = me.store, view = me.view, rows = view.all, elCount = rows.getCount(), start, end, lockingPartner = me.view.lockingPartner && me.view.lockingPartner.bufferedRenderer, diff = elCount - viewSize, i, j, records, oldRows, newRows, storeCount; if (lockingPartner && !fromLockingPartner && lockingPartner.view.componentLayoutCounter) { if (lockingPartner.viewSize > viewSize) { viewSize = lockingPartner.viewSize; } else { lockingPartner.setViewSize(viewSize, true); } } diff = elCount - viewSize; if (diff) { me.scrollTop = view.getScrollY(); me.viewSize = viewSize; if (store.isBufferedStore) { store.setViewSize(viewSize); } if (elCount) { storeCount = store.getCount(); start = rows.startIndex; end = Math.min(start + viewSize - 1, storeCount - 1); if (!(start === rows.startIndex && end === rows.endIndex)) { if (lockingPartner) { lockingPartner.disable(); } if (diff < 0) { if (storeCount > elCount) { store.getRange(rows.endIndex + 1, end, { callback: function(records, start) { newRows = view.doAdd(records, start); view.fireEvent('itemadd', records, start, newRows); } }); } } else { start = rows.endIndex - (diff - 1); end = rows.endIndex; oldRows = rows.slice(start, end + 1); rows.removeRange(start, end, true); if (view.hasListeners.itemremove) { records = store.getRange(start, end); for (i = end , j = records.length - 1; j >= 0; --i , --j) { view.fireEvent('itemremove', records[j], i, oldRows[j]); } } } if (lockingPartner) { lockingPartner.enable(); } } } } return viewSize; }, getViewRange: function() { var me = this, rows = me.view.all, store = me.store, startIndex = 0; if (rows.getCount()) { startIndex = rows.startIndex; } else if (store.isBufferedStore) { if (!store.currentPage) { store.currentPage = 1; } startIndex = rows.startIndex = (store.currentPage - 1) * (store.pageSize || 1); store.currentPage = 1; } if (store.data.getCount()) { return store.getRange(startIndex, startIndex + (me.viewSize || store.defaultViewSize) - 1); } else { return []; } }, onReplace: function(store, startIndex, oldRecords, newRecords) { var me = this, view = me.view, rows = view.all, oldStartIndex, renderedSize = rows.getCount(), lastAffectedIndex = startIndex + oldRecords.length - 1, recordIncrement = newRecords.length - oldRecords.length, scrollIncrement = recordIncrement * me.rowHeight; if (startIndex >= rows.startIndex + me.viewSize) { me.refreshSize(); return; } if (renderedSize && lastAffectedIndex < rows.startIndex) { rows.moveBlock(recordIncrement); me.refreshSize(); oldStartIndex = rows.startIndex; if (recordIncrement > 0) { me.doNotMirror = true; me.handleViewScroll(-1); me.doNotMirror = false; } if (rows.startIndex === oldStartIndex) { if (rows.startIndex) { me.setBodyTop(me.bodyTop += scrollIncrement); view.suspendEvent('scroll'); view.scrollBy(0, scrollIncrement); view.resumeEvent('scroll'); me.position = me.scrollTop = view.getScrollY(); } } else { view.suspendEvent('scroll'); view.scrollBy(0, (oldStartIndex - rows.startIndex) * me.rowHeight); view.resumeEvent('scroll'); } view.refreshSize(rows.getCount() !== renderedSize); return; } if (renderedSize && startIndex > rows.endIndex) { me.refreshSize(); if (recordIncrement > 0) { me.onRangeFetched(null, rows.startIndex, Math.min(store.getCount(), rows.startIndex + me.viewSize) - 1, null, true); } view.refreshSize(rows.getCount() !== renderedSize); return; } if (startIndex < rows.startIndex && lastAffectedIndex < rows.endIndex) { me.refreshView(rows.startIndex - oldRecords.length + newRecords.length); return; } if (startIndex < rows.startIndex && lastAffectedIndex <= rows.endIndex && scrollIncrement) { view.suspendEvent('scroll'); view.setScrollY(me.position = me.scrollTop += scrollIncrement); view.resumeEvent('scroll'); } me.refreshView(); }, scrollTo: function(recordIdx, options) { var args = arguments, me = this, view = me.view, lockingPartner = view.lockingPartner && view.lockingPartner.grid.isVisible() && view.lockingPartner.bufferedRenderer, viewDom = view.el.dom, store = me.store, total = store.getCount(), startIdx, endIdx, targetRow, tableTop, groupingFeature, metaGroup, record, direction, scrollDecrement = 0, doSelect, doFocus, animate, highlight, callback, scope; if (options && typeof options === 'object') { doSelect = options.select; doFocus = options.focus; highlight = options.highlight; animate = options.animate; callback = options.callback; scope = options.scope; } else { doSelect = args[1]; callback = args[2]; scope = args[3]; } if ((groupingFeature = view.dataSource.groupingFeature) && (groupingFeature.collapsible)) { if (recordIdx.isEntity) { record = recordIdx; } else { record = view.store.getAt(Math.min(Math.max(recordIdx, 0), view.store.getCount() - 1)); } metaGroup = groupingFeature.getMetaGroup(record); if (metaGroup && metaGroup.isCollapsed) { groupingFeature.expand(groupingFeature.getGroup(record).getGroupKey()); total = store.getCount(); } recordIdx = groupingFeature.indexOf(record); } else { if (recordIdx.isEntity) { record = recordIdx; recordIdx = store.indexOf(record); if (recordIdx === -1) { Ext.Error.raise('Unknown record passed to BufferedRenderer#scrollTo'); return; } } else { recordIdx = Math.min(Math.max(recordIdx, 0), total - 1); record = store.getAt(recordIdx); } } if (record && (targetRow = view.getNode(record))) { view.getScrollable().scrollIntoView(targetRow, null, animate, highlight); me.onViewScroll(); if (doSelect) { view.selModel.select(record); } if (doFocus) { view.getNavigationModel().setPosition(record, 0); } if (callback) { callback.call(scope || me, recordIdx, record, targetRow); } return; } if (recordIdx < view.all.startIndex) { direction = -1; startIdx = Math.max(Math.min(recordIdx - (Math.floor((me.leadingBufferZone + me.trailingBufferZone) / 2)), total - me.viewSize + 1), 0); endIdx = Math.min(startIdx + me.viewSize - 1, total - 1); } else { direction = 1; endIdx = Math.min(recordIdx + (Math.floor((me.leadingBufferZone + me.trailingBufferZone) / 2)), total - 1); startIdx = Math.max(endIdx - (me.viewSize - 1), 0); } tableTop = Math.max(startIdx * me.rowHeight, 0); store.getRange(startIdx, endIdx, { callback: function(range, start, end) { var scroller = view.getScrollable(); me.renderRange(start, end, true, true); record = store.data.getRange(recordIdx, recordIdx + 1)[0]; targetRow = view.getNode(record); view.body.translate(null, me.bodyTop = tableTop); if (direction === 1) { me.refreshSize(); } if (lockingPartner) { lockingPartner.renderRange(start, end, true, true); me.syncRowHeights(); lockingPartner.view.body.translate(null, lockingPartner.bodyTop = tableTop); if (direction === 1) { lockingPartner.refreshSize(); } } if (!targetRow) { return; } if (direction === 1) { scrollDecrement = viewDom.clientHeight - targetRow.offsetHeight; } me.position = me.scrollTop = Math.min(Math.max(0, tableTop - view.body.getOffsetsTo(targetRow)[1]) - scrollDecrement, scroller.getSize().y - viewDom.clientHeight); if (lockingPartner) { lockingPartner.position = lockingPartner.scrollTop = me.scrollTop; } scroller.scrollIntoView(targetRow, null, animate, highlight); if (doSelect) { view.selModel.select(record); } if (doFocus) { view.getNavigationModel().setPosition(record, 0); } if (callback) { callback.call(scope || me, recordIdx, record, targetRow); } } }); }, onViewScroll: function() { var me = this, store = me.store, totalCount = (store.getCount()), vscrollDistance, scrollDirection, scrollTop = me.scrollTop = me.view.getScrollY(); if (!(me.disabled || totalCount < me.viewSize)) { vscrollDistance = scrollTop - me.position; scrollDirection = vscrollDistance > 0 ? 1 : -1; if (Math.abs(vscrollDistance) >= 20 || (scrollDirection !== me.lastScrollDirection)) { me.lastScrollDirection = scrollDirection; me.handleViewScroll(me.lastScrollDirection); } } }, handleViewScroll: function(direction) { var me = this, rows = me.view.all, store = me.store, viewSize = me.viewSize, lastItemIndex = (store.getCount()) - 1, requestStart, requestEnd; if (direction === -1) { if (rows.startIndex) { if (me.topOfViewCloseToEdge()) { requestStart = Math.max(0, me.getLastVisibleRowIndex() + me.trailingBufferZone - viewSize); } } } else { if (rows.endIndex < lastItemIndex) { if (me.bottomOfViewCloseToEdge()) { requestStart = Math.max(0, me.getFirstVisibleRowIndex() - me.trailingBufferZone); } } } if (requestStart == null) { me.loadId++; } else { requestEnd = Math.min(requestStart + viewSize - 1, lastItemIndex); if (me.variableRowHeight && requestEnd === rows.endIndex && requestEnd < lastItemIndex) { requestEnd++; me.viewSize = viewSize++; if (store.isBufferedStore) { store.setViewSize(me.viewSize); } } if (requestStart !== rows.startIndex || requestEnd !== rows.endIndex) { me.renderRange(requestStart, requestEnd); return true; } } }, bottomOfViewCloseToEdge: function() { var me = this; if (me.variableRowHeight) { return me.bodyTop + me.view.body.dom.offsetHeight < me.scrollTop + me.view.lastBox.height + (me.numFromEdge * me.rowHeight); } else { return (me.view.all.endIndex - me.getLastVisibleRowIndex()) < me.numFromEdge; } }, topOfViewCloseToEdge: function() { var me = this; if (me.variableRowHeight) { return me.bodyTop > me.scrollTop - (me.numFromEdge * me.rowHeight); } else { return (me.getFirstVisibleRowIndex() - me.view.all.startIndex) < me.numFromEdge; } }, refreshView: function(startIndex) { var me = this, viewSize = me.viewSize, rows = me.view.all, store = me.store, storeCount = store.getCount(), maxIndex = storeCount - 1, endIndex; if (storeCount < viewSize) { startIndex = 0; endIndex = maxIndex; } else { startIndex = Math.max(0, Math.min(startIndex == null ? rows.startIndex : startIndex, maxIndex - (viewSize - me.leadingBufferZone) + 1)); endIndex = Math.min(startIndex + viewSize - 1, maxIndex); if (endIndex - startIndex + 1 > viewSize) { startIndex = endIndex - viewSize + 1; } } store.getRange(startIndex, endIndex, { callback: me.doRefreshView, scope: me }); }, doRefreshView: function(range, startIndex, endIndex, options) { var me = this, view = me.view, navModel = view.getNavigationModel(), focusPosition = navModel.getPosition(), rows = view.all, previousStartIndex = rows.startIndex, previousEndIndex = rows.endIndex, previousFirstItem, previousLastItem, prevRowCount = rows.getCount(), newNodes, viewMoved = startIndex !== rows.startIndex, calculatedTop, scrollIncrement; if (view.refreshCounter) { if (focusPosition && focusPosition.view === view) { if (focusPosition.rowIdx < startIndex || focusPosition.rowIdx > endIndex) { focusPosition = null; } else { focusPosition = focusPosition.clone(); } navModel.setPosition(); } else { focusPosition = null; } view.refreshing = me.refreshing = true; view.clearViewEl(true); view.refreshCounter++; if (range.length) { newNodes = view.doAdd(range, startIndex); if (viewMoved) { previousFirstItem = rows.item(previousStartIndex, true); previousLastItem = rows.item(previousEndIndex, true); if (previousFirstItem) { scrollIncrement = -previousFirstItem.offsetTop; } else if (previousLastItem) { scrollIncrement = previousLastItem.offsetTop + previousLastItem.offsetHeight; } if (scrollIncrement) { me.setBodyTop(me.bodyTop += scrollIncrement); view.suspendEvent('scroll'); view.setScrollY(me.position = me.scrollTop = me.bodyTop ? me.scrollTop + scrollIncrement : 0); view.resumeEvent('scroll'); } else { me.setBodyTop(me.bodyTop = calculatedTop = startIndex * me.rowHeight); view.suspendEvent('scroll'); view.setScrollY(me.position = me.scrollTop = Math.max(calculatedTop - me.rowHeight * (calculatedTop < me.bodyTop ? me.leadingBufferZone : me.trailingBufferZone , 0))); view.resumeEvent('scroll'); } } } else { view.addEmptyText(); } me.refreshSize(); view.refreshSize(rows.getCount() !== prevRowCount); view.fireEvent('refresh', view, range); if (focusPosition) { view.cellFocused = true; navModel.setPosition(focusPosition, null, null, null, true); } view.headerCt.setSortState(); view.refreshNeeded = view.refreshing = me.refreshing = false; } else { view.refresh(); } }, renderRange: function(start, end, forceSynchronous, fromLockingPartner) { var me = this, rows = me.view.all, store = me.store; if (!(start === rows.startIndex && end === rows.endIndex)) { if (store.rangeCached(start, end)) { me.cancelLoad(); if (me.synchronousRender || forceSynchronous) { me.onRangeFetched(null, start, end, null, fromLockingPartner); } else { if (!me.renderTask) { me.renderTask = new Ext.util.DelayedTask(me.onRangeFetched, me, null, false); } me.renderTask.delay(1, null, null, [ null, start, end, null, fromLockingPartner ]); } } else { me.attemptLoad(start, end); } } }, onRangeFetched: function(range, start, end, options, fromLockingPartner) { var me = this, view = me.view, oldStart, rows = view.all, removeCount, increment = 0, calculatedTop, newTop, lockingPartner = (view.lockingPartner && !fromLockingPartner && !me.doNotMirror) && view.lockingPartner.bufferedRenderer, newRows, partnerNewRows, topAdditionSize, topBufferZone, i, variableRowHeight = me.variableRowHeight; if (view.isDestroyed) { return; } if (range) { me.scrollTop = me.view.getScrollY(); } else { range = me.store.getRange(start, end); if (!range) { return; } } calculatedTop = start * me.rowHeight; if (start < rows.startIndex && end > rows.endIndex) { topAdditionSize = rows.startIndex - start; view.clearViewEl(true); newRows = view.doAdd(range, start); view.fireEvent('itemadd', range, start, newRows); for (i = 0; i < topAdditionSize; i++) { increment -= newRows[i].offsetHeight; } newTop = me.bodyTop + increment; } else { if (me.teleported || start > rows.endIndex || end < rows.startIndex) { newTop = calculatedTop; if (variableRowHeight) { topBufferZone = me.scrollTop < me.position ? me.leadingBufferZone : me.trailingBufferZone; if (start > topBufferZone) { newTop = me.scrollTop - me.rowHeight * topBufferZone; } } view.clearViewEl(true); me.teleported = false; } if (!rows.getCount()) { newRows = view.doAdd(range, start); view.fireEvent('itemadd', range, start, newRows); } else if (end > rows.endIndex) { removeCount = Math.max(start - rows.startIndex, 0); if (variableRowHeight) { increment = rows.item(rows.startIndex + removeCount, true).offsetTop; } newRows = rows.scroll(Ext.Array.slice(range, rows.endIndex + 1 - start), 1, removeCount, start, end); if (variableRowHeight) { newTop = me.bodyTop + increment; } else { newTop = calculatedTop; } } else { removeCount = Math.max(rows.endIndex - end, 0); oldStart = rows.startIndex; newRows = rows.scroll(Ext.Array.slice(range, 0, rows.startIndex - start), -1, removeCount, start, end); if (variableRowHeight) { newTop = me.bodyTop - rows.item(oldStart, true).offsetTop; if (!rows.startIndex) { if (newTop) { view.setScrollY(me.position = (me.scrollTop -= newTop)); newTop = 0; } } else if (newTop < 0) { increment = rows.startIndex * me.rowHeight; view.setScrollY(me.position = (me.scrollTop += increment)); newTop = me.bodyTop + increment; } } else { newTop = calculatedTop; } } me.position = me.scrollTop; } newTop = Math.max(Math.floor(newTop), 0); if (view.positionBody) { me.setBodyTop(newTop); } if (newRows && lockingPartner && !lockingPartner.disabled) { lockingPartner.scrollTop = lockingPartner.position = me.scrollTop; partnerNewRows = lockingPartner.onRangeFetched(null, start, end, options, true); if (lockingPartner.bodyTop !== newTop) { lockingPartner.setBodyTop(newTop); } lockingPartner.view.setScrollY(me.scrollTop); if (variableRowHeight && view.ownerGrid.syncRowHeights) { me.syncRowHeights(newRows, partnerNewRows); } } return newRows; }, syncRowHeights: function(itemEls, partnerItemEls) { var me = this, ln = 0, otherLn = 1, mySynchronizer = [], otherSynchronizer = [], RowSynchronizer = Ext.grid.locking.RowSynchronizer, i, rowSync; if (itemEls && partnerItemEls) { ln = itemEls.length; otherLn = partnerItemEls.length; } if (ln !== otherLn) { itemEls = me.view.all.slice(); partnerItemEls = me.view.lockingPartner.all.slice(); ln = otherLn = itemEls.length; } for (i = 0; i < ln; i++) { mySynchronizer[i] = rowSync = new RowSynchronizer(me.view, itemEls[i]); rowSync.measure(); } for (i = 0; i < otherLn; i++) { otherSynchronizer[i] = rowSync = new RowSynchronizer(me.view.lockingPartner, partnerItemEls[i]); rowSync.measure(); } for (i = 0; i < ln; i++) { mySynchronizer[i].finish(otherSynchronizer[i]); otherSynchronizer[i].finish(mySynchronizer[i]); } me.syncRowHeightsFinish(); }, syncRowHeightsFinish: function() { var me = this, view = me.view, lockingPartner = view.lockingPartner.bufferedRenderer; delete me.rowHeight; me.refreshSize(); if (lockingPartner.rowHeight !== me.rowHeight) { delete lockingPartner.rowHeight; lockingPartner.refreshSize(); } }, setBodyTop: function(bodyTop) { var me = this, view = me.view, store = me.store, body = view.body; body.translate((me.isRTL && Ext.supports.xOriginBug && view.scrollFlags.y) ? Ext.getScrollbarSize().width : null, me.bodyTop = bodyTop); if (me.variableRowHeight) { if (view.all.endIndex === (store.getCount()) - 1) { me.stretchView(view, me.scrollHeight = me.bodyTop + body.dom.offsetHeight - 1); } else if (me.bodyTop + body.dom.offsetHeight - 1 > me.scrollHeight) { me.stretchView(view, me.scrollHeight += ((store.getCount()) - view.all.endIndex) * me.rowHeight); } } }, getFirstVisibleRowIndex: function(startRow, endRow, viewportTop, viewportBottom) { var me = this, view = me.view, rows = view.all, elements = rows.elements, clientHeight = me.viewClientHeight, target, targetTop, bodyTop = me.bodyTop; if (rows.getCount() && me.variableRowHeight) { if (!arguments.length) { startRow = rows.startIndex; endRow = rows.endIndex; viewportTop = me.scrollTop; viewportBottom = viewportTop + clientHeight; if (bodyTop > viewportBottom || bodyTop + view.body.dom.offsetHeight < viewportTop) { me.teleported = true; return Math.floor(me.scrollTop / me.rowHeight); } target = startRow + Math.min(me.numFromEdge + ((me.lastScrollDirection === -1) ? me.leadingBufferZone : me.trailingBufferZone), Math.floor((endRow - startRow) / 2)); } else { target = startRow + Math.floor((endRow - startRow) / 2); } targetTop = bodyTop + elements[target].offsetTop; if (targetTop + elements[target].offsetHeight <= viewportTop) { return me.getFirstVisibleRowIndex(target + 1, endRow, viewportTop, viewportBottom); } if (targetTop <= viewportTop) { return target; } else if (target !== startRow) { return me.getFirstVisibleRowIndex(startRow, target - 1, viewportTop, viewportBottom); } } return Math.floor(me.scrollTop / me.rowHeight); }, getLastVisibleRowIndex: function(startRow, endRow, viewportTop, viewportBottom) { var me = this, view = me.view, rows = view.all, elements = rows.elements, clientHeight = me.viewClientHeight, target, targetTop, targetBottom, bodyTop = me.bodyTop; if (rows.getCount() && me.variableRowHeight) { if (!arguments.length) { startRow = rows.startIndex; endRow = rows.endIndex; viewportTop = me.scrollTop; viewportBottom = viewportTop + clientHeight; if (bodyTop > viewportBottom || bodyTop + view.body.dom.offsetHeight < viewportTop) { me.teleported = true; return Math.floor(me.scrollTop / me.rowHeight) + Math.ceil(clientHeight / me.rowHeight); } target = endRow - Math.min(me.numFromEdge + ((me.lastScrollDirection === 1) ? me.leadingBufferZone : me.trailingBufferZone), Math.floor((endRow - startRow) / 2)); } else { target = startRow + Math.floor((endRow - startRow) / 2); } targetTop = bodyTop + elements[target].offsetTop; if (targetTop > viewportBottom) { return me.getLastVisibleRowIndex(startRow, target - 1, viewportTop, viewportBottom); } targetBottom = targetTop + elements[target].offsetHeight; if (targetBottom >= viewportBottom) { return target; } else if (target !== endRow) { return me.getLastVisibleRowIndex(target + 1, endRow, viewportTop, viewportBottom); } } return me.getFirstVisibleRowIndex() + Math.ceil(clientHeight / me.rowHeight); }, getScrollHeight: function(calculatedOnly) { var me = this, view = me.view, rows = view.all, store = me.store, recCount = store.getCount(), rowCount, scrollHeight; if (!recCount) { return 0; } if (!me.hasOwnProperty('rowHeight')) { rowCount = rows.getCount(); if (rowCount) { me.rowHeight = me.variableRowHeight ? Math.floor(view.body.dom.clientHeight / rowCount) : rows.first(true).offsetHeight; } } scrollHeight = Math.floor(recCount * me.rowHeight); if (!calculatedOnly) { if (scrollHeight && (rows.endIndex === recCount - 1)) { scrollHeight = Math.max(scrollHeight, me.bodyTop + view.body.dom.offsetHeight - 1); } } return me.scrollHeight = scrollHeight; }, attemptLoad: function(start, end) { var me = this; if (me.scrollToLoadBuffer) { if (!me.loadTask) { me.loadTask = new Ext.util.DelayedTask(me.doAttemptLoad, me, []); } me.loadTask.delay(me.scrollToLoadBuffer, me.doAttemptLoad, me, [ start, end ]); } else { me.doAttemptLoad(start, end); } }, cancelLoad: function() { if (this.loadTask) { this.loadTask.cancel(); } }, doAttemptLoad: function(start, end) { var me = this; this.store.getRange(start, end, { loadId: ++me.loadId, callback: function(range, start, end, options) { if (options.loadId === me.loadId) { this.onRangeFetched(range, start, end, options); } }, scope: this, fireEvent: false }); }, destroy: function() { var me = this, view = me.view; me.cancelLoad(); if (view && view.el) { view.un('scroll', me.onViewScroll, me); } Ext.destroy(me.viewListeners, me.storeListeners, me.gridListeners, me.stretcher); } }, function(cls) { if (Ext.supports.Touch) { cls.prototype.leadingBufferZone = cls.prototype.trailingBufferZone = 2; cls.prototype.numFromEdge = 1; } }); Ext.define('Ext.grid.plugin.Editing', { extend: 'Ext.plugin.Abstract', alias: 'editing.editing', requires: [ 'Ext.grid.column.Column', 'Ext.util.KeyNav', 'Ext.form.field.Base', 'Ext.view.Table' ], mixins: { observable: 'Ext.util.Observable' }, clicksToEdit: 2, triggerEvent: undefined, relayedEvents: [ 'beforeedit', 'edit', 'validateedit', 'canceledit' ], defaultFieldUI: 'default', defaultFieldXType: 'textfield', editStyle: '', constructor: function(config) { var me = this; me.callParent([ config ]); me.mixins.observable.constructor.call(me); me.on("edit", function(editor, e) { me.fireEvent("afteredit", editor, e); }); }, init: function(grid) { var me = this; me.grid = grid; me.view = grid.view; me.initEvents(); if (grid.rendered) { me.setup(); } else { me.mon(grid, { beforereconfigure: me.onBeforeReconfigure, reconfigure: me.onReconfigure, scope: me, beforerender: { fn: me.onBeforeRender, single: true, scope: me } }); } grid.relayEvents(me, me.relayedEvents); if (me.grid.ownerLockable) { me.grid.ownerLockable.relayEvents(me, me.relayedEvents); } grid.isEditable = true; grid.editingPlugin = grid.view.editingPlugin = me; }, onBeforeReconfigure: function() { this.reconfiguring = true; }, onReconfigure: function() { this.setup(); delete this.reconfiguring; }, onBeforeRender: function() { this.setup(); }, setup: function() { this.initFieldAccessors(this.grid.getTopLevelColumnManager().getColumns()); }, destroy: function() { var me = this, grid = me.grid; Ext.destroy(me.keyNav); me.clearListeners(); if (grid) { grid.editingPlugin = grid.view.editingPlugin = me.grid = me.view = me.editor = me.keyNav = null; } }, getEditStyle: function() { return this.editStyle; }, initFieldAccessors: function(columns) { if (columns.isGroupHeader) { columns = columns.getGridColumns(); } else if (!Ext.isArray(columns)) { columns = [ columns ]; } var me = this, c, cLen = columns.length, getEditor = function(record, defaultField) { return me.getColumnField(this, defaultField); }, hasEditor = function() { return me.hasColumnField(this); }, setEditor = function(field) { me.setColumnField(this, field); }, column; for (c = 0; c < cLen; c++) { column = columns[c]; if (!column.getEditor) { column.getEditor = getEditor; } if (!column.hasEditor) { column.hasEditor = hasEditor; } if (!column.setEditor) { column.setEditor = setEditor; } } }, removeFieldAccessors: function(columns) { if (columns.isGroupHeader) { columns = columns.getGridColumns(); } else if (!Ext.isArray(columns)) { columns = [ columns ]; } var c, cLen = columns.length, column; for (c = 0; c < cLen; c++) { column = columns[c]; column.getEditor = column.hasEditor = column.setEditor = column.field = column.editor = null; } }, getColumnField: function(columnHeader, defaultField) { var me = this, field = columnHeader.field; if (!(field && field.isFormField)) { field = columnHeader.field = me.createColumnField(columnHeader, defaultField); } if (field && field.ui === 'default' && !field.hasOwnProperty('ui')) { field.ui = me.defaultFieldUI; } return field; }, hasColumnField: function(columnHeader) { return !!(columnHeader.field && columnHeader.field.isComponent); }, setColumnField: function(columnHeader, field) { columnHeader.field = field; columnHeader.field = this.createColumnField(columnHeader); }, createColumnField: function(column, defaultField) { var field = column.field, dataIndex; if (!field && column.editor) { field = column.editor; column.editor = null; } if (!field && defaultField) { field = defaultField; } if (field) { dataIndex = column.dataIndex; if (field.isComponent) { field.column = column; } else { if (Ext.isString(field)) { field = { name: dataIndex, xtype: field, column: column }; } else { field = Ext.apply({ name: dataIndex, column: column }, field); } field = Ext.ComponentManager.create(field, this.defaultFieldXType); } field.dataIndex = dataIndex; field.isEditorComponent = true; column.field = field; } return field; }, initEvents: function() { var me = this; me.initEditTriggers(); me.initCancelTriggers(); }, initCancelTriggers: Ext.emptyFn, initEditTriggers: function() { var me = this, view = me.view; if (me.triggerEvent === 'cellfocus') { me.mon(view, 'cellfocus', me.onCellFocus, me); } else if (me.triggerEvent === 'rowfocus') { me.mon(view, 'rowfocus', me.onRowFocus, me); } else { if (view.getSelectionModel().isCellModel) { view.onCellFocus = me.beforeViewCellFocus.bind(me); } me.mon(view, me.triggerEvent || ('cell' + (me.clicksToEdit === 1 ? 'click' : 'dblclick')), me.onCellClick, me); } me.initAddRemoveHeaderEvents(); me.view.getNavigationModel().addKeyBindings({ enter: me.onEnterKey, esc: me.onEscKey, scope: me }); }, beforeViewCellFocus: function(position) { if (this.view.selModel.keyNavigation || !this.editing || !this.isCellEditable || !this.isCellEditable(position.row, position.columnHeader)) { this.view.focusCell.apply(this.view, arguments); } }, onRowFocus: function(record, row, rowIdx) { this.startEdit(row, 0); }, onCellFocus: function(record, cell, position) { this.startEdit(position.row, position.column); }, onCellClick: function(view, cell, colIdx, record, row, rowIdx, e) { var expanderSelector = view.expanderSelector, columnHeader = view.ownerCt.getColumnManager().getHeaderAtIndex(colIdx), editor = columnHeader.getEditor(record); if (this.shouldStartEdit(editor) && (!expanderSelector || !e.getTarget(expanderSelector))) { this.startEdit(record, columnHeader); } }, initAddRemoveHeaderEvents: function() { var me = this, headerCt = me.grid.headerCt; me.mon(headerCt, { scope: me, add: me.onColumnAdd, columnmove: me.onColumnMove, beforedestroy: me.beforeGridHeaderDestroy }); }, onColumnAdd: function(ct, column) { this.initFieldAccessors(column); }, onColumnMove: Ext.emptyFn, onEnterKey: function(e) { var me = this, grid = me.grid, navModel, record, pos, column, targetComponent; if (me.editing) { targetComponent = Ext.getCmp(e.getTarget().getAttribute('componentId')); if (!(targetComponent && targetComponent.isPickerField && targetComponent.isExpanded)) { me.completeEdit(); } } else if (e.view === me.view) { navModel = grid.getView().getNavigationModel(); pos = navModel.getPosition(); if (pos) { record = pos.record; column = pos.column; } if (record && column) { me.startEdit(record, column); } } }, onEscKey: function(e) { if (this.editing) { var targetComponent = Ext.getCmp(e.getTarget().getAttribute('componentId')); if (!(targetComponent && targetComponent.isPickerField && targetComponent.isExpanded)) { return this.cancelEdit(); } } }, beforeEdit: Ext.emptyFn, shouldStartEdit: function(editor) { return !!editor; }, startEdit: function(record, columnHeader) { var me = this, context, layoutView = me.grid.lockable ? me.grid : me.view; if (!layoutView.componentLayoutCounter) { layoutView.on({ boxready: Ext.Function.bind(me.startEdit, me, [ record, columnHeader ]), single: true }); return false; } if (me.disabled || me.grid.collapsed || !me.grid.view.isVisible(true)) { return false; } context = me.getEditingContext(record, columnHeader); if (context == null) { return false; } if (!me.preventBeforeCheck) { if (me.beforeEdit(context) === false || me.fireEvent('beforeedit', me, context) === false || context.cancel) { return false; } } return context; }, getEditingContext: function(record, columnHeader) { var me = this, grid = me.grid, colMgr = grid.visibleColumnManager, view, gridRow, rowIdx, colIdx, result; if (Ext.isNumber(columnHeader)) { columnHeader = colMgr.getHeaderAtIndex(columnHeader); } if (!columnHeader) { return; } if (columnHeader.hidden) { columnHeader = columnHeader.next(':not([hidden])') || columnHeader.prev(':not([hidden])'); } view = columnHeader.getRootHeaderCt().view; gridRow = view.getRow(record); if (!gridRow) { return; } colIdx = colMgr.getHeaderIndex(columnHeader); if (Ext.isNumber(record)) { rowIdx = record; record = view.getRecord(gridRow); } else { rowIdx = view.indexOf(gridRow); } if (!record) { return; } result = new Ext.grid.CellContext(view).setAll(view, rowIdx, colIdx, record, columnHeader); result.grid = grid; result.store = view.dataSource; result.field = columnHeader.dataIndex; result.value = result.originalValue = record.get(columnHeader.dataIndex); result.row = gridRow; result.node = view.getNode(record); return result; }, cancelEdit: function() { var me = this; me.editing = false; me.fireEvent('canceledit', me, me.context); }, completeEdit: function() { var me = this; if (me.editing && me.validateEdit()) { me.fireEvent('edit', me, me.context); } me.context = null; me.editing = false; }, validateEdit: function() { var me = this, context = me.context; return me.fireEvent('validateedit', me, context) !== false && !context.cancel; } }); Ext.define('Ext.grid.plugin.CellEditing', { alias: 'plugin.cellediting', extend: 'Ext.grid.plugin.Editing', requires: [ 'Ext.grid.CellEditor', 'Ext.util.DelayedTask' ], lockableScope: 'both', init: function(grid) { var me = this, lockingPartner = me.lockingPartner; me.callParent(arguments); if (lockingPartner) { if (lockingPartner.editors) { me.editors = lockingPartner.editors; } else { me.editors = lockingPartner.editors = new Ext.util.MixedCollection(false, function(editor) { return editor.editorId; }); } } else { me.editors = new Ext.util.MixedCollection(false, function(editor) { return editor.editorId; }); } }, beforeGridHeaderDestroy: function(headerCt) { var me = this, columns = me.grid.getColumnManager().getColumns(), len = columns.length, i, column, editor; for (i = 0; i < len; i++) { column = columns[i]; editor = me.editors.getByKey(column.getItemId()); if (!editor) { editor = column.editor || column.field; } Ext.destroy(editor); me.removeFieldAccessors(column); } }, onReconfigure: function(grid, store, columns) { if (columns) { this.editors.clear(); } this.callParent(); }, destroy: function() { var me = this; if (me.editors) { me.editors.each(Ext.destroy, Ext); me.editors.clear(); } me.callParent(arguments); }, initCancelTriggers: function() { var me = this, grid = me.grid; me.mon(grid, { columnresize: me.cancelEdit, columnmove: me.cancelEdit, scope: me }); }, isCellEditable: function(record, columnHeader) { var me = this, context = me.getEditingContext(record, columnHeader); if (me.grid.view.isVisible(true) && context) { columnHeader = context.column; record = context.record; if (columnHeader && me.getEditor(record, columnHeader)) { return true; } } }, startEdit: function(record, columnHeader, context) { var me = this, useCurrentActiveEditor, isFieldEditable, currentActiveEditor, newEditor; if (!context) { me.preventBeforeCheck = true; context = me.callParent(arguments); delete me.preventBeforeCheck; if (context === false) { return false; } } if (context && context.view.isVisible(true)) { record = context.record; columnHeader = context.column; isFieldEditable = (columnHeader && columnHeader.getEditor(record)) && !(me.beforeEdit(context) === false || me.fireEvent('beforeedit', me, context) === false || context.cancel); if (isFieldEditable) { currentActiveEditor = me.getActiveEditor(); newEditor = me.getEditor(record, columnHeader); if (currentActiveEditor) { useCurrentActiveEditor = newEditor === currentActiveEditor; me.completeEdit(!!newEditor); if (me.editing) { return false; } } } else { return false; } me.context = context; context.view.scrollCellIntoView(context.view.getCell(record, columnHeader)); if (newEditor) { if (useCurrentActiveEditor) { newEditor.editing = false; if (Ext.isIE) { newEditor.selectSameEditor = true; } } me.showEditor(newEditor, context, context.value); if (currentActiveEditor && !useCurrentActiveEditor) { currentActiveEditor.hide(); } return true; } return false; } }, showEditor: function(ed, context, value) { var me = this, record = context.record, view = context.view, columnHeader = context.column, sm = view.getSelectionModel(), selectMode; if (!columnHeader.up(me.view.ownerCt)) { return me.lockingPartner.showEditor(ed, me.lockingPartner.getEditingContext(record, columnHeader), value); } me.setEditingContext(context); selectMode = sm.getSelectionMode(); if (!sm.isCellSelected(view, record, columnHeader) && (selectMode !== 'MULTI' || !sm.getSelection().length || (sm.getSelection().length === 1 && sm.isSelected(record)))) { sm.selectByPosition({ row: record, column: columnHeader, view: view }, selectMode === 'MULTI'); } if (!view.cellFocused) { view.getNavigationModel().setPosition(context, null, null, null, true); } view.getNavigationModel().setPosition(); ed.startEdit(view.getCell(record, columnHeader), value, context); if (ed.editing) { me.setActiveEditor(ed); me.setActiveRecord(record); me.setActiveColumn(columnHeader); me.editing = true; me.scroll = view.el.getScroll(); } else { view.getNavigationModel().setPosition(context, null, null, null, true); } }, completeEdit: function(remainVisible) { var activeEd = this.getActiveEditor(); if (activeEd) { activeEd.completeEdit(remainVisible); } }, setEditingContext: function(context) { this.context = context; if (this.lockingPartner) { this.lockingPartner.context = context; } }, setActiveEditor: function(ed) { this.activeEditor = ed; if (this.lockingPartner) { this.lockingPartner.activeEditor = ed; } }, getActiveEditor: function() { return this.activeEditor; }, setActiveColumn: function(column) { this.activeColumn = column; if (this.lockingPartner) { this.lockingPartner.activeColumn = column; } }, getActiveColumn: function() { return this.activeColumn; }, setActiveRecord: function(record) { this.activeRecord = record; if (this.lockingPartner) { this.lockingPartner.activeRecord = record; } }, getActiveRecord: function() { return this.activeRecord; }, getEditor: function(record, column) { var me = this, editors = me.editors, editorId = column.getItemId(), editor = editors.getByKey(editorId), editorOwner = me.grid.ownerLockable || me.grid; if (!editor) { editor = column.getEditor(record); if (!editor) { return false; } if (editor instanceof Ext.grid.CellEditor) { editor.floating = true; } else { editor = new Ext.grid.CellEditor({ floating: true, editorId: editorId, field: editor }); } editor.field.excludeForm = true; if (editor.ownerCt !== editorOwner) { editorOwner.add(editor); editor.on({ scope: me, specialkey: me.onSpecialKey, complete: me.onEditComplete, canceledit: me.cancelEdit }); column.on('removed', me.onColumnRemoved, me); } editors.add(editor); } if (column.isTreeColumn) { editor.isForTree = column.isTreeColumn; editor.addCls(Ext.baseCSSPrefix + 'tree-cell-editor'); } editor.setGrid(me.grid); editor.editingPlugin = me; return editor; }, onColumnRemoved: function(column) { var me = this, context = me.context, editor, editorOwner = me.grid.ownerLockable || me.grid; if (context && context.column === column) { me.cancelEdit(); } column.un('removed', me.onColumnRemoved, me); if (column.getEditor && (editor = column.getEditor()) && editor.ownerCt === editorOwner) { editorOwner.remove(editor); editor.un({ scope: me, specialkey: me.onSpecialKey, complete: me.onEditComplete, canceledit: me.cancelEdit }); } }, setColumnField: function(column, field) { var ed = this.editors.getByKey(column.getItemId()); Ext.destroy(ed, column.field); this.editors.removeAtKey(column.getItemId()); this.callParent(arguments); }, getCell: function(record, column) { return this.grid.getView().getCell(record, column); }, onSpecialKey: function(ed, field, e) { var sm; if (e.getKey() === e.TAB) { e.stopEvent(); e.position = this.context; if (ed) { ed.onEditorTab(e); } sm = ed.getRefOwner().getSelectionModel(); return sm.onEditorTab(ed.editingPlugin, e); } }, onEditComplete: function(ed, value, startValue) { var me = this, activeColumn = me.getActiveColumn(), context = me.context, view, record; if (activeColumn) { view = context.view; record = context.record; me.setActiveEditor(null); me.setActiveColumn(null); me.setActiveRecord(null); context.value = value; if (!me.validateEdit()) { me.editing = false; return; } if (!record.isEqual(value, startValue)) { record.set(activeColumn.dataIndex, value); context.rowIdx = view.indexOf(record); } me.fireEvent('edit', me, context); me.editing = false; } }, cancelEdit: function() { var me = this, context = me.context, view, sm, record, preserveCurrentSelection, activeEd = me.getActiveEditor(); if (activeEd) { me.setActiveEditor(null); me.setActiveColumn(null); me.setActiveRecord(null); view = context.view; sm = view.getSelectionModel(); preserveCurrentSelection = sm.getSelectionMode() === 'MULTI' && (sm.getSelection().length > 1 || !sm.isSelected(record)); if (activeEd.field) { me.context.value = ('editedValue' in activeEd) ? activeEd.editedValue : activeEd.getValue(); activeEd.cancelEdit(); } context.view.getNavigationModel().deferSetPosition(100, context, null, null, null, preserveCurrentSelection); me.callParent(arguments); return; } return true; }, startEditByPosition: function(position) { var me = this, cm = me.grid.getColumnManager(), index; if (!position.isCellContext) { position.column = me.grid.getColumnManager().getColumns()[position.column]; position.record = me.view.dataSource.getAt(position.row); } index = cm.getHeaderIndex(position.column); position.column = cm.getVisibleHeaderClosestToIndex(index); return me.startEdit(position.record, position.column); } }); Ext.define('Ext.plugin.AbstractClipboard', { extend: 'Ext.plugin.Abstract', requires: [ 'Ext.util.KeyMap' ], cachedConfig: { formats: { text: { get: 'getTextData', put: 'putTextData' } } }, config: { memory: null, source: 'system', system: 'text' }, destroy: function() { var me = this, keyMap = me.keyMap, shared = me.shared; if (keyMap) { me.keyMap = Ext.destroy(keyMap); if (!--shared.counter) { shared.textArea = Ext.destroy(shared.textArea); } } else { me.renderListener = Ext.destroy(me.renderListener); } me.callParent(); }, init: function(comp) { var me = this; if (comp.rendered) { this.finishInit(comp); } else { me.renderListener = comp.on({ render: function() { me.renderListener = null; me.finishInit(comp); }, destroyable: true, single: true }); } }, privates: { shared: { counter: 0, data: null, textArea: null }, applyMemory: function(value) { value = this.applySource(value); if (value) { for (var i = value.length; i-- > 0; ) { if (value[i] === 'system') { Ext.Error.raise('Invalid clipboard format "' + value[i] + '"'); } } } return value; }, applySource: function(value) { if (value) { if (Ext.isString(value)) { value = [ value ]; } else if (value.length === 0) { value = null; } } if (value) { var formats = this.getFormats(); for (var i = value.length; i-- > 0; ) { if (value[i] !== 'system' && !formats[value[i]]) { Ext.Error.raise('Invalid clipboard format "' + value[i] + '"'); } } } return value || null; }, applySystem: function(value) { var formats = this.getFormats(); if (!formats[value]) { Ext.Error.raise('Invalid clipboard format "' + value + '"'); } return value; }, doCutCopy: function(event, erase) { var me = this, formats = me.allFormats || me.syncFormats(), data = me.getData(erase, formats), memory = me.getMemory(), system = me.getSystem(), sys; me.shared.data = memory && data; if (system) { sys = data[system]; if (formats[system] < 3) { delete data[system]; } me.setClipboardData(sys); } }, doPaste: function(format, data) { var formats = this.getFormats(); this[formats[format].put](data, format); }, finishInit: function(comp) { var me = this; me.keyMap = new Ext.util.KeyMap({ target: comp.el, binding: [ { ctrl: true, key: 'x', fn: me.onCut, scope: me }, { ctrl: true, key: 'c', fn: me.onCopy, scope: me }, { ctrl: true, key: 'v', fn: me.onPaste, scope: me } ] }); ++me.shared.counter; comp.on({ destroy: 'destroy', scope: me }); }, getData: function(erase, format) { var me = this, formats = me.getFormats(), data, i, name, names; if (Ext.isString(format)) { if (!formats[format]) { Ext.Error.raise('Invalid clipboard format "' + format + '"'); } data = me[formats[format].get](format, erase); } else { data = {}; names = []; if (format) { for (name in format) { if (!formats[name]) { Ext.Error.raise('Invalid clipboard format "' + name + '"'); } names.push(name); } } else { names = Ext.Object.getAllKeys(formats); } for (i = names.length; i-- > 0; ) { data[name] = me[formats[name].get](name, erase && !i); } } return data; }, getHiddenTextArea: function() { var shared = this.shared, ret = shared.textArea; if (!ret) { shared.textArea = ret = Ext.getBody().createChild({ tag: 'textarea', tabIndex: -1, style: { position: 'absolute', top: '-1000px', width: '1px' } }); } return ret; }, onCopy: function(event) { this.doCutCopy(event, false); }, onCut: function(event) { this.doCutCopy(event, true); }, onPaste: function() { var me = this, sharedData = me.shared.data, source = me.getSource(), i, n, s; if (source) { for (i = 0 , n = source.length; i < n; ++i) { s = source[i]; if (s === 'system') { s = me.getSystem(); me.pasteClipboardData(s); break; } else if (sharedData && (s in sharedData)) { me.doPaste(s, sharedData[s]); break; } } } }, pasteClipboardData: function(format) { var me = this, clippy = window.clipboardData, area, focusEl; if (clippy && clippy.getData) { me.doPaste(format, clippy.getData("text")); } else { focusEl = Ext.Element.getActiveElement(); area = me.getHiddenTextArea().dom; area.value = ''; area.focus(); Ext.defer(function() { if (focusEl) { focusEl.focus(); } me.doPaste(format, area.value); area.value = ''; }, 100, me); } }, setClipboardData: function(data) { var clippy = window.clipboardData; if (clippy && clippy.setData) { clippy.setData("text", data); } else { var me = this, area = me.getHiddenTextArea().dom, focusEl = Ext.Element.getActiveElement(); area.value = data; area.focus(); area.select(); Ext.defer(function() { area.value = ''; if (focusEl) { focusEl.focus(); } }, 50); } }, syncFormats: function() { var me = this, map = {}, memory = me.getMemory(), system = me.getSystem(), i, s; if (system) { map[system] = 1; } if (memory) { for (i = memory.length; i-- > 0; ) { s = memory[i]; map[s] = map[s] ? 3 : 2; } } return me.allFormats = map; }, updateMemory: function() { this.allFormats = null; }, updateSystem: function() { this.allFormats = null; } } }); Ext.define('Ext.grid.plugin.Clipboard', { extend: 'Ext.plugin.AbstractClipboard', alias: 'plugin.clipboard', requires: [ 'Ext.util.Format', 'Ext.util.TSV' ], formats: { cell: { get: 'getCells' }, html: { get: 'getCellData' }, raw: { get: 'getCellData' } }, getCellData: function(format, erase) { var cmp = this.getCmp(), selModel = cmp.getSelectionModel(), ret = [], isRaw = format === 'raw', isText = format === 'text', viewNode, cell, data, dataIndex, lastRecord, record, row, view; selModel.getSelected().eachCell(function(cellContext) { view = cellContext.column.getView(); record = cellContext.record; if (lastRecord !== record) { lastRecord = record; ret.push(row = []); } dataIndex = cellContext.column.dataIndex; if (isRaw) { data = record.data[dataIndex]; } else { viewNode = view.all.item(cellContext.rowIdx); if (!viewNode) { viewNode = Ext.fly(view.createRowElement(record, cellContext.rowIdx)); } cell = viewNode.down(cellContext.column.getCellInnerSelector()); data = cell.dom.innerHTML; if (isText) { data = Ext.util.Format.stripTags(data); } } row.push(data); if (erase && dataIndex) { record.set(dataIndex, null); } }); return Ext.util.TSV.encode(ret); }, getCells: function(format, erase) { var cmp = this.getCmp(), selModel = cmp.getSelectionModel(), ret = [], dataIndex, lastRecord, record, row; selModel.getSelected().eachCell(function(cellContext) { record = cellContext.record; if (lastRecord !== record) { lastRecord = record; ret.push(row = { model: record.self, fields: [] }); } dataIndex = cellContext.column.dataIndex; row.fields.push({ name: dataIndex, value: record.data[dataIndex] }); if (erase && dataIndex) { record.set(dataIndex, null); } }); return ret; }, getTextData: function(format, erase) { return this.getCellData(format, erase); }, putCellData: function(data, format) { var values = Ext.util.TSV.decode(data), row, recCount = values.length, colCount = recCount ? values[0].length : 0, sourceRowIdx, sourceColIdx, view = this.getCmp().getView(), maxRowIdx = view.dataSource.getCount() - 1, maxColIdx = view.getVisibleColumnManager().getColumns().length - 1, navModel = view.getNavigationModel(), destination = navModel.getPosition(), dataIndex, destinationStartColumn, dataObject = {}; if (destination) { destination = new Ext.grid.CellContext(view).setPosition(destination.record, destination.column); } else { destination = new Ext.grid.CellContext(view).setPosition(0, 0); } destinationStartColumn = destination.colIdx; for (sourceRowIdx = 0; sourceRowIdx < recCount; sourceRowIdx++) { row = values[sourceRowIdx]; for (sourceColIdx = 0; sourceColIdx < colCount; sourceColIdx++) { dataIndex = destination.column.dataIndex; if (dataIndex) { switch (format) { case 'raw': dataObject[dataIndex] = row[sourceColIdx]; break; case 'text': dataObject[dataIndex] = row[sourceColIdx]; break; case 'html': break; } } if (destination.colIdx === maxColIdx) { break; } destination.setColumn(destination.colIdx + 1); } destination.record.set(dataObject); if (destination.rowIdx === maxRowIdx) { break; } destination.setPosition(destination.rowIdx + 1, destinationStartColumn); } }, putTextData: function(data, format) { this.putCellData(data, format); } }); Ext.define('Ext.grid.plugin.DragDrop', { extend: 'Ext.plugin.Abstract', alias: 'plugin.gridviewdragdrop', uses: [ 'Ext.view.DragZone', 'Ext.grid.ViewDropZone' ], dragText: '{0} selected row{1}', ddGroup: "GridDD", enableDrop: true, enableDrag: true, containerScroll: false, init: function(view) { view.on('render', this.onViewRender, this, { single: true }); }, destroy: function() { Ext.destroy(this.dragZone, this.dropZone); }, enable: function() { var me = this; if (me.dragZone) { me.dragZone.unlock(); } if (me.dropZone) { me.dropZone.unlock(); } me.callParent(); }, disable: function() { var me = this; if (me.dragZone) { me.dragZone.lock(); } if (me.dropZone) { me.dropZone.lock(); } me.callParent(); }, onViewRender: function(view) { var me = this, scrollEl; if (me.enableDrag) { if (me.containerScroll) { scrollEl = view.getEl(); } me.dragZone = new Ext.view.DragZone(Ext.apply({ view: view, ddGroup: me.dragGroup || me.ddGroup, dragText: me.dragText, containerScroll: me.containerScroll, scrollEl: scrollEl }, me.dragZone)); } if (me.enableDrop) { me.dropZone = new Ext.grid.ViewDropZone(Ext.apply({ view: view, ddGroup: me.dropGroup || me.ddGroup }, me.dropZone)); } } }); Ext.define('Ext.grid.plugin.RowEditing', { extend: 'Ext.grid.plugin.Editing', alias: 'plugin.rowediting', requires: [ 'Ext.grid.RowEditor' ], lockableScope: 'top', editStyle: 'row', autoCancel: true, errorSummary: true, constructor: function() { var me = this; me.callParent(arguments); if (!me.clicksToMoveEditor) { me.clicksToMoveEditor = me.clicksToEdit; } me.autoCancel = !!me.autoCancel; }, destroy: function() { Ext.destroy(this.editor); this.callParent(arguments); }, onBeforeReconfigure: function() { this.callParent(arguments); this.cancelEdit(); }, onReconfigure: function(grid, store, columns) { var ed = this.editor; this.callParent(arguments); if (columns && ed && ed.rendered) { ed.needsSyncFieldWidths = true; } }, shouldStartEdit: function(editor) { return true; }, startEdit: function(record, columnHeader) { var me = this, editor = me.getEditor(), context; if (Ext.isEmpty(columnHeader)) { columnHeader = me.grid.getTopLevelVisibleColumnManager().getHeaderAtIndex(0); } if (editor.beforeEdit() !== false) { context = me.callParent([ record, columnHeader ]); if (context) { me.context = context; if (me.lockingPartner) { me.lockingPartner.cancelEdit(); } editor.startEdit(context.record, context.column, context); me.editing = true; return true; } } return false; }, cancelEdit: function() { var me = this; if (me.editing) { me.getContextFieldValues(); me.getEditor().cancelEdit(); me.callParent(arguments); return; } return true; }, completeEdit: function() { var me = this; if (me.editing && me.validateEdit()) { me.editing = false; me.fireEvent('edit', me, me.context); } }, validateEdit: function() { this.getContextFieldValues(); return this.callParent(arguments) && this.getEditor().completeEdit(); }, getEditor: function() { var me = this; if (!me.editor) { me.editor = me.initEditor(); } return me.editor; }, getContextFieldValues: function() { var editor = this.editor, context = this.context, record = context.record, newValues = {}, originalValues = {}, editors = editor.query('>[isFormField]'), len = editors.length, i, name, item; for (i = 0; i < len; i++) { item = editors[i]; name = item.dataIndex; newValues[name] = item.getValue(); originalValues[name] = record.get(name); } Ext.apply(context, { newValues: newValues, originalValues: originalValues }); }, initEditor: function() { return new Ext.grid.RowEditor(this.initEditorConfig()); }, initEditorConfig: function() { var me = this, grid = me.grid, view = me.view, headerCt = grid.headerCt, btns = [ 'saveBtnText', 'cancelBtnText', 'errorsText', 'dirtyText' ], b, bLen = btns.length, cfg = { autoCancel: me.autoCancel, errorSummary: me.errorSummary, fields: headerCt.getGridColumns(), hidden: true, view: view, editingPlugin: me }, item; for (b = 0; b < bLen; b++) { item = btns[b]; if (Ext.isDefined(me[item])) { cfg[item] = me[item]; } } return cfg; }, initEditTriggers: function() { var me = this, view = me.view, moveEditorEvent = me.clicksToMoveEditor === 1 ? 'click' : 'dblclick'; me.callParent(arguments); if (me.clicksToMoveEditor !== me.clicksToEdit) { me.mon(view, 'cell' + moveEditorEvent, me.moveEditorByClick, me); } view.on({ render: function() { me.mon(me.grid.headerCt, { scope: me, columnresize: me.onColumnResize, columnhide: me.onColumnHide, columnshow: me.onColumnShow }); }, single: true }); }, moveEditorByClick: function() { var me = this; if (me.editing) { me.superclass.onCellClick.apply(me, arguments); } }, onColumnAdd: function(ct, column) { if (column.isHeader) { var me = this, editor; me.initFieldAccessors(column); editor = me.editor; if (editor) { editor.onColumnAdd(column); } } }, beforeGridHeaderDestroy: function(headerCt) { var columns = this.grid.getColumnManager().getColumns(), len = columns.length, i, column, field; for (i = 0; i < len; i++) { column = columns[i]; if (column.hasEditor) { if (column.hasEditor() && (field = column.getEditor())) { field.destroy(); } this.removeFieldAccessors(column); } } }, onColumnResize: function(ct, column, width) { if (column.isHeader) { var me = this, editor = me.getEditor(); if (editor) { editor.onColumnResize(column, width); } } }, onColumnHide: function(ct, column) { var me = this, editor = me.getEditor(); if (editor) { editor.onColumnHide(column); } }, onColumnShow: function(ct, column) { var me = this, editor = me.getEditor(); if (editor) { editor.onColumnShow(column); } }, onColumnMove: function(ct, column, fromIdx, toIdx) { var me = this, editor = me.getEditor(); me.initFieldAccessors(column); if (editor) { editor.onColumnMove(column, fromIdx, toIdx); } }, setColumnField: function(column, field) { var me = this, editor = me.getEditor(); if (editor) { editor.destroyColumnEditor(column); } me.callParent(arguments); if (editor) { editor.insertColumnEditor(column); } }, createColumnField: function(column, defaultField) { var editor = this.editor, def; if (editor) { def = editor.getDefaultFieldCfg(); } return this.callParent([ column, defaultField || def ]); } }); Ext.define('Ext.grid.plugin.RowExpander', { extend: 'Ext.plugin.Abstract', lockableScope: 'normal', requires: [ 'Ext.grid.feature.RowBody' ], alias: 'plugin.rowexpander', columnWidth: 24, rowBodyTpl: null, lockedTpl: null, expandOnEnter: true, expandOnDblClick: true, selectRowOnExpand: false, headerWidth: 24, bodyBefore: false, rowBodyTrSelector: '.' + Ext.baseCSSPrefix + 'grid-rowbody-tr', rowBodyHiddenCls: Ext.baseCSSPrefix + 'grid-row-body-hidden', rowCollapsedCls: Ext.baseCSSPrefix + 'grid-row-collapsed', addCollapsedCls: { fn: function(out, values, parent) { var me = this.rowExpander; if (!me.recordsExpanded[values.record.internalId]) { values.itemClasses.push(me.rowCollapsedCls); } this.nextTpl.applyOut(values, out, parent); }, syncRowHeights: function(lockedItem, normalItem) { this.rowExpander.syncRowHeights(lockedItem, normalItem); }, priority: 20000 }, setCmp: function(grid) { var me = this, features; me.callParent(arguments); me.recordsExpanded = {}; if (!me.rowBodyTpl) { Ext.Error.raise("The 'rowBodyTpl' config is required and is not defined."); } me.rowBodyTpl = Ext.XTemplate.getTpl(me, 'rowBodyTpl'); features = me.getFeatureConfig(grid); if (grid.features) { grid.features = Ext.Array.push(features, grid.features); } else { grid.features = features; } }, getFeatureConfig: function(grid) { var me = this, features = [], featuresCfg = { ftype: 'rowbody', rowExpander: me, bodyBefore: me.bodyBefore, recordsExpanded: me.recordsExpanded, rowBodyHiddenCls: me.rowBodyHiddenCls, rowCollapsedCls: me.rowCollapsedCls, setupRowData: me.getRowBodyFeatureData, setup: me.setup }; features.push(Ext.apply({ lockableScope: 'normal', getRowBodyContents: me.getRowBodyContentsFn(me.rowBodyTpl) }, featuresCfg)); if (grid.enableLocking) { features.push(Ext.apply({ lockableScope: 'locked', getRowBodyContents: me.lockedTpl ? me.getRowBodyContentsFn(me.lockedTpl) : function() { return ''; } }, featuresCfg)); } return features; }, getRowBodyContentsFn: function(rowBodyTpl) { var me = this; return function(rowValues) { rowBodyTpl.owner = me; return rowBodyTpl.applyTemplate(rowValues.record.getData()); }; }, init: function(grid) { if (grid.lockable) { grid = grid.normalGrid; } var me = this, ownerLockable = grid.ownerLockable, view, lockedView; me.callParent(arguments); me.grid = grid; view = me.view = grid.getView(); me.bindView(view); view.addRowTpl(me.addCollapsedCls).rowExpander = me; if (ownerLockable) { me.addExpander(ownerLockable.lockedGrid.headerCt.items.getCount() ? ownerLockable.lockedGrid : grid); lockedView = ownerLockable.lockedGrid.getView(); me.bindView(lockedView); lockedView.addRowTpl(me.addCollapsedCls).rowExpander = me; ownerLockable.syncRowHeight = true; ownerLockable.mon(ownerLockable, { processcolumns: me.onLockableProcessColumns, lockcolumn: me.onColumnLock, unlockcolumn: me.onColumnUnlock, scope: me }); me.viewListeners = view.on({ itemadd: Ext.Function.createAnimationFrame(ownerLockable.syncRowHeights, ownerLockable) }); } else { me.addExpander(grid); grid.on('beforereconfigure', me.beforeReconfigure, me); } }, beforeReconfigure: function(grid, store, columns, oldStore, oldColumns) { var me = this; if (me.viewListeners) { me.viewListeners.destroy(); } if (columns) { me.expanderColumn = new Ext.grid.Column(me.getHeaderConfig()); columns.unshift(me.expanderColumn); } }, onLockableProcessColumns: function(lockable, lockedHeaders, normalHeaders) { this.addExpander(lockedHeaders.length ? lockable.lockedGrid : lockable.normalGrid); }, addExpander: function(expanderGrid) { var me = this, expanderHeader = me.getHeaderConfig(); if (expanderGrid.isLocked && expanderGrid.ownerLockable.shrinkWrapLocked) { expanderGrid.width += expanderHeader.width; me.grid = expanderGrid; } me.expanderColumn = expanderGrid.headerCt.insert(0, expanderHeader); expanderGrid.getSelectionModel().injectCheckbox = 1; }, getRowBodyFeatureData: function(record, idx, rowValues) { var me = this; me.self.prototype.setupRowData.apply(me, arguments); rowValues.rowBody = me.getRowBodyContents(rowValues); rowValues.rowBodyCls = me.recordsExpanded[record.internalId] ? '' : me.rowBodyHiddenCls; }, setup: function(rows, rowValues) { var me = this, lockable = me.grid.ownerLockable; me.self.prototype.setup.apply(me, arguments); if (lockable && Ext.Array.indexOf(me.grid.columnManager.getColumns(), me.rowExpander.expanderColumn) !== -1) { rowValues.rowBodyColspan -= 1; } }, bindView: function(view) { if (this.expandOnEnter) { view.on('itemkeydown', this.onKeyDown, this); } if (this.expandOnDblClick) { view.on('itemdblclick', this.onDblClick, this); } }, onKeyDown: function(view, record, row, rowIdx, e) { if (e.getKey() === e.ENTER) { var ds = view.store, sels = view.getSelectionModel().getSelection(), ln = sels.length, i = 0; for (; i < ln; i++) { rowIdx = ds.indexOf(sels[i]); this.toggleRow(rowIdx, sels[i]); } } }, onDblClick: function(view, record, row, rowIdx, e) { this.toggleRow(rowIdx, record); }, toggleRow: function(rowIdx, record) { var me = this, view = me.view, bufferedRenderer = view.bufferedRenderer, scroller = view.getScrollable(), fireView = view, rowNode = view.getNode(rowIdx), normalRow = Ext.fly(rowNode), lockedRow, nextBd = normalRow.down(me.rowBodyTrSelector, true), wasCollapsed = normalRow.hasCls(me.rowCollapsedCls), addOrRemoveCls = wasCollapsed ? 'removeCls' : 'addCls', rowSpan = wasCollapsed ? 2 : 1, ownerLockable = me.grid.ownerLockable, expanderCell; normalRow[addOrRemoveCls](me.rowCollapsedCls); Ext.fly(nextBd)[addOrRemoveCls](me.rowBodyHiddenCls); me.recordsExpanded[record.internalId] = wasCollapsed; if (me.grid.ownerLockable) { fireView = ownerLockable.getView(); if (ownerLockable.lockedGrid.isVisible()) { view = ownerLockable.view.lockedGrid.view; lockedRow = Ext.fly(view.getNode(rowIdx)); if (lockedRow) { lockedRow[addOrRemoveCls](me.rowCollapsedCls); nextBd = lockedRow.down(me.rowBodyTrSelector, true); Ext.fly(nextBd)[addOrRemoveCls](me.rowBodyHiddenCls); } } } if (me.expanderColumn) { expanderCell = Ext.fly(view.getRow(rowIdx)).down(me.expanderColumn.getCellSelector(), true); if (expanderCell) { expanderCell.rowSpan = rowSpan; } } fireView.fireEvent(wasCollapsed ? 'expandbody' : 'collapsebody', rowNode, record, nextBd); if (view.getSizeModel().height.shrinkWrap || ownerLockable) { view.refreshSize(true); } if (scroller) { if (bufferedRenderer) { bufferedRenderer.refreshSize(); } else { scroller.refresh(true); } } }, syncRowHeights: function(lockedItem, normalItem) { var me = this, lockedBd = Ext.fly(lockedItem).down(me.rowBodyTrSelector), normalBd = Ext.fly(normalItem).down(me.rowBodyTrSelector), lockedHeight, normalHeight; if (normalBd.isVisible()) { if ((lockedHeight = lockedBd.getHeight()) !== (normalHeight = normalBd.getHeight())) { if (lockedHeight > normalHeight) { normalBd.setHeight(lockedHeight); } else { lockedBd.setHeight(normalHeight); } } } else { lockedBd.dom.style.height = normalBd.dom.style.height = ''; } }, onColumnUnlock: function(lockable, column) { var me = this, lockedColumns; lockable = me.grid.ownerLockable; lockedColumns = lockable.lockedGrid.visibleColumnManager.getColumns(); if (lockedColumns.length === 1) { if (lockedColumns[0] === me.expanderColumn) { lockable.unlock(me.expanderColumn); me.grid = lockable.normalGrid; } else { lockable.lock(me.expanderColumn, 0); } } }, onColumnLock: function(lockable, column) { var me = this, lockedColumns, lockedGrid; lockable = me.grid.ownerLockable; lockedColumns = lockable.lockedGrid.visibleColumnManager.getColumns(); if (lockedColumns.length === 1) { me.grid = lockedGrid = lockable.lockedGrid; lockedGrid.headerCt.insert(0, me.expanderColumn); } }, getHeaderConfig: function() { var me = this, lockable = me.grid.ownerLockable; return { width: me.headerWidth, lockable: false, autoLock: true, sortable: false, resizable: false, draggable: false, hideable: false, menuDisabled: true, tdCls: Ext.baseCSSPrefix + 'grid-cell-special', innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-row-expander', renderer: function() { return ''; }, processEvent: function(type, view, cell, rowIndex, cellIndex, e, record) { if (e.getTarget('.' + Ext.baseCSSPrefix + 'grid-row-expander')) { if (type === "click") { me.toggleRow(rowIndex, record); return me.selectRowOnExpand; } } }, isLocked: function() { return lockable && (lockable.lockedGrid.isVisible() || this.locked); }, editRenderer: function() { return ' '; } }; } }); Ext.define('Ext.grid.property.Grid', { extend: 'Ext.grid.Panel', alias: 'widget.propertygrid', alternateClassName: 'Ext.grid.PropertyGrid', 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', 'Ext.form.field.ComboBox' ], valueField: 'value', nameField: 'name', inferTypes: true, enableColumnMove: false, columnLines: true, stripeRows: false, trackMouseOver: false, clicksToEdit: 1, enableHdMenu: false, gridCls: Ext.baseCSSPrefix + 'property-grid', initComponent: function() { var me = this; me.source = me.source || {}; me.addCls(me.gridCls); me.plugins = me.plugins || []; me.plugins.push(new Ext.grid.plugin.CellEditing({ clicksToEdit: me.clicksToEdit, startEdit: function(record, column) { return this.self.prototype.startEdit.call(this, record, me.valueColumn); } })); me.selModel = { type: 'cellmodel', onCellSelect: function(position) { position.column = me.valueColumn; position.colIdx = me.valueColumn.getVisibleIndex(); return this.self.prototype.onCellSelect.call(this, position); } }; me.sourceConfig = Ext.apply({}, me.sourceConfig); if (!me.store) { me.propStore = me.store = new Ext.grid.property.Store(me, me.source); } me.configure(me.sourceConfig); if (me.sortableColumns) { me.store.sort('name', 'ASC'); } me.columns = new Ext.grid.property.HeaderContainer(me, me.store); me.callParent(); me.getView().walkCells = this.walkCells; me.editors = { 'date': new Ext.grid.CellEditor({ field: new Ext.form.field.Date({ selectOnFocus: true }) }), 'string': new Ext.grid.CellEditor({ field: new Ext.form.field.Text({ selectOnFocus: true }) }), 'number': new Ext.grid.CellEditor({ field: new Ext.form.field.Number({ selectOnFocus: true }) }), 'boolean': new Ext.grid.CellEditor({ field: new Ext.form.field.ComboBox({ editable: false, store: [ [ true, me.headerCt.trueText ], [ false, me.headerCt.falseText ] ] }) }) }; me.store.on('update', me.onUpdate, me); }, configure: function(config) { var me = this, store = me.store, i = 0, len = me.store.getCount(), nameField = me.nameField, valueField = me.valueField, name, value, rec, type; me.configureLegacy(config); if (me.inferTypes) { for (; i < len; ++i) { rec = store.getAt(i); name = rec.get(nameField); if (!me.getConfigProp(name, 'type')) { value = rec.get(valueField); if (Ext.isDate(value)) { type = 'date'; } else if (Ext.isNumber(value)) { type = 'number'; } else if (Ext.isBoolean(value)) { type = 'boolean'; } else { type = 'string'; } me.setConfigProp(name, 'type', type); } } } }, getConfigProp: function(fieldName, key, defaultValue) { var config = this.sourceConfig[fieldName], out; if (config) { out = config[key]; } return out || defaultValue; }, setConfigProp: function(fieldName, key, value) { var sourceCfg = this.sourceConfig, o = sourceCfg[fieldName]; if (!o) { o = sourceCfg[fieldName] = { __copied: true }; } else if (!o.__copied) { o = Ext.apply({ __copied: true }, o); sourceCfg[fieldName] = o; } o[key] = value; return value; }, configureLegacy: function(config) { var me = this; me.copyLegacyObject(config, me.customRenderers, 'renderer'); me.copyLegacyObject(config, me.customEditors, 'editor'); me.copyLegacyObject(config, me.propertyNames, 'displayName'); if (me.customRenderers || me.customEditors || me.propertyNames) { if (Ext.global.console && Ext.global.console.warn) { Ext.global.console.warn(this.$className, 'customRenderers, customEditors & propertyNames have been consolidated into a new config, see "sourceConfig". These configurations will be deprecated.'); } } }, copyLegacyObject: function(config, o, keyName) { var key; for (key in o) { if (o.hasOwnProperty(key)) { if (!config[key]) { config[key] = {}; } config[key][keyName] = o[key]; } } }, onUpdate: function(store, record, operation) { var me = this, v, oldValue; if (me.rendered && operation === Ext.data.Model.EDIT) { v = record.get(me.valueField); oldValue = record.modified.value; if (me.fireEvent('beforepropertychange', me.source, record.getId(), v, oldValue) !== false) { if (me.source) { me.source[record.getId()] = v; } record.commit(); me.fireEvent('propertychange', me.source, record.getId(), v, oldValue); } else { record.reject(); } } }, walkCells: function(pos, direction, e, preventWrap, verifierFn, scope) { var me = this, valueColumn = me.ownerCt.valueColumn; if (direction === 'left') { direction = 'up'; } else if (direction === 'right') { direction = 'down'; } pos = Ext.view.Table.prototype.walkCells.call(me, pos, direction, e, preventWrap, verifierFn, scope); pos.column = valueColumn; pos.colIdx = valueColumn.getVisibleIndex(); return pos; }, getCellEditor: function(record, column) { var me = this, propName = record.get(me.nameField), val = record.get(me.valueField), editor = me.getConfigProp(propName, 'editor'), type = me.getConfigProp(propName, 'type'), editors = me.editors; if (editor) { if (!(editor instanceof Ext.grid.CellEditor)) { if (!(editor instanceof Ext.form.field.Base)) { editor = Ext.ComponentManager.create(editor, 'textfield'); } editor = me.setConfigProp(propName, 'editor', new Ext.grid.CellEditor({ field: editor })); } } else if (type) { switch (type) { case 'date': editor = editors.date; break; case 'number': editor = editors.number; break; case 'boolean': editor = me.editors['boolean']; break; default: editor = editors.string; } } else if (Ext.isDate(val)) { editor = editors.date; } else if (Ext.isNumber(val)) { editor = editors.number; } else if (Ext.isBoolean(val)) { editor = editors['boolean']; } else { editor = editors.string; } editor.editorId = propName; editor.field.column = me.valueColumn; return editor; }, beforeDestroy: function() { var me = this; me.callParent(); me.destroyEditors(me.editors); me.destroyEditors(me.customEditors); delete me.source; }, destroyEditors: function(editors) { for (var ed in editors) { if (editors.hasOwnProperty(ed)) { Ext.destroy(editors[ed]); } } }, setSource: function(source, sourceConfig) { var me = this; me.source = source; if (sourceConfig !== undefined) { me.sourceConfig = Ext.apply({}, sourceConfig); me.configure(me.sourceConfig); } me.propStore.setSource(source); }, getSource: function() { return this.propStore.getSource(); }, getProperty: function(prop) { return this.propStore.getProperty(prop); }, setProperty: function(prop, value, create) { this.propStore.setValue(prop, value, create); }, removeProperty: function(prop) { this.propStore.remove(prop); } }); Ext.define('Ext.grid.property.HeaderContainer', { extend: 'Ext.grid.header.Container', alternateClassName: 'Ext.grid.PropertyColumnModel', nameWidth: 115, nameText: 'Name', valueText: 'Value', dateFormat: 'm/j/Y', trueText: 'true', falseText: 'false', nameColumnCls: Ext.baseCSSPrefix + 'grid-property-name', nameColumnInnerCls: Ext.baseCSSPrefix + 'grid-cell-inner-property-name', constructor: function(grid, store) { var me = this; me.grid = grid; me.store = store; me.callParent([ { isRootHeader: true, enableColumnResize: Ext.isDefined(grid.enableColumnResize) ? grid.enableColumnResize : me.enableColumnResize, enableColumnMove: Ext.isDefined(grid.enableColumnMove) ? grid.enableColumnMove : me.enableColumnMove, items: [ { header: me.nameText, width: grid.nameColumnWidth || me.nameWidth, sortable: grid.sortableColumns, dataIndex: grid.nameField, scope: me, renderer: me.renderProp, itemId: grid.nameField, menuDisabled: true, tdCls: me.nameColumnCls, innerCls: me.nameColumnInnerCls }, { header: me.valueText, scope: me, renderer: me.renderCell, getEditor: me.getCellEditor.bind(me), sortable: grid.sortableColumns, flex: 1, fixed: true, dataIndex: grid.valueField, itemId: grid.valueField, menuDisabled: true } ] } ]); me.grid.valueColumn = me.items.getAt(1); }, getCellEditor: function(record) { return this.grid.getCellEditor(record, this); }, renderProp: function(v) { return this.getPropertyName(v); }, renderCell: function(val, meta, rec) { var me = this, grid = me.grid, renderer = grid.getConfigProp(rec.get(grid.nameField), 'renderer'), result = val; if (renderer) { return renderer.apply(me, arguments); } if (Ext.isDate(val)) { result = me.renderDate(val); } else if (Ext.isBoolean(val)) { result = me.renderBool(val); } return Ext.util.Format.htmlEncode(result); }, renderDate: Ext.util.Format.date, renderBool: function(bVal) { return this[bVal ? 'trueText' : 'falseText']; }, getPropertyName: function(name) { return this.grid.getConfigProp(name, 'displayName', name); } }); Ext.define('Ext.grid.property.Property', { extend: 'Ext.data.Model', alternateClassName: 'Ext.PropGridProperty', fields: [ { name: 'name', type: 'string' }, { name: 'value' } ], idProperty: 'name', constructor: function(data, value) { if (!Ext.isObject(data)) { data = { name: data, value: value }; } this.callParent([ data ]); } }); Ext.define('Ext.grid.property.Reader', { extend: 'Ext.data.reader.Reader', successProperty: null, totalProperty: null, messageProperty: null, read: function(dataObject) { return this.readRecords(dataObject); }, readRecords: function(dataObject) { var Model = this.getModel(), result = { records: [], success: true }, val, propName; for (propName in dataObject) { if (dataObject.hasOwnProperty(propName)) { val = dataObject[propName]; if (this.isEditableValue(val)) { result.records.push(new Model({ name: propName, value: val })); } } } result.total = result.count = result.records.length; return new Ext.data.ResultSet(result); }, isEditableValue: function(val) { return Ext.isPrimitive(val) || Ext.isDate(val) || val === null; } }); Ext.define('Ext.grid.property.Store', { extend: 'Ext.data.Store', alternateClassName: 'Ext.grid.PropertyStore', remoteSort: true, requires: [ 'Ext.grid.property.Reader', 'Ext.data.proxy.Memory', 'Ext.grid.property.Property' ], constructor: function(grid, source) { var me = this; me.grid = grid; me.source = source; me.callParent([ { data: source, model: Ext.grid.property.Property, proxy: me.getProxy() } ]); }, getProxy: function() { var proxy = this.proxy; if (!proxy) { proxy = this.proxy = new Ext.data.proxy.Memory({ model: Ext.grid.property.Property, reader: this.getReader() }); } return proxy; }, getReader: function() { var reader = this.reader; if (!reader) { reader = this.reader = new Ext.grid.property.Reader({ model: Ext.grid.property.Property }); } return reader; }, setSource: function(dataObject) { var me = this; me.source = dataObject; me.suspendEvents(); me.removeAll(); me.getProxy().setData(dataObject); me.load(); me.resumeEvents(); me.fireEvent('datachanged', me); me.fireEvent('refresh', me); }, getProperty: function(row) { var rec = Ext.isNumber(row) ? this.getAt(row) : this.getById(row), ret = null; if (rec) { ret = rec.get('value'); } return ret; }, setValue: function(prop, value, create) { var me = this, rec = me.getRec(prop); if (rec) { rec.set('value', value); me.source[prop] = value; } else if (create) { me.source[prop] = value; rec = new Ext.grid.property.Property({ name: prop, value: value }, prop); me.add(rec); } }, remove: function(prop) { var rec = this.getRec(prop); if (rec) { this.callParent([ rec ]); delete this.source[prop]; } }, getRec: function(prop) { return this.getById(prop); }, getSource: function() { return this.source; }, onDestroy: function() { Ext.destroy(this.reader, this.proxy); this.callParent(); } }); Ext.define('Ext.grid.selection.Selection', { constructor: function(view) { if (!view || !(view.isTableView || view.isLockingView)) { Ext.Error.raise('Selection must be created for a given TableView or LockingView'); } this.view = view.ownerGrid.view; } }); Ext.define('Ext.grid.selection.Cells', { extend: 'Ext.grid.selection.Selection', type: 'cells', isCells: true, clone: function() { var me = this, result = new me.self(me.view); if (me.startCell) { result.startCell = me.startCell.clone(); result.endCell = me.endCell.clone(); } return result; }, contains: function(cellContext) { var range; if (!cellContext || !cellContext.isCellContext) { return false; } if (this.startCell) { range = this.getRowRange(); if (cellContext.rowIdx >= range[0] && cellContext.rowIdx <= range[1]) { range = this.getColumnRange(); return (cellContext.colIdx >= range[0] && cellContext.colIdx <= range[1]); } } return false; }, eachRow: function(fn, scope) { var me = this, rowRange = me.getRowRange(), context = new Ext.grid.CellContext(me.view), rowIdx; for (rowIdx = rowRange[0]; rowIdx <= rowRange[1]; rowIdx++) { context.setRow(rowIdx); if (fn.call(scope || me, context.record) === false) { return; } } }, eachColumn: function(fn, scope) { var me = this, colRange = me.getColumnRange(), context = new Ext.grid.CellContext(me.view), colIdx; for (colIdx = colRange[0]; colIdx <= colRange[1]; colIdx++) { context.setColumn(colIdx); if (fn.call(scope || me, context.column, colIdx) === false) { return; } } }, eachCell: function(fn, scope) { var me = this, rowRange = me.getRowRange(), colRange = me.getColumnRange(), context = new Ext.grid.CellContext(me.view), rowIdx, colIdx; for (rowIdx = rowRange[0]; rowIdx <= rowRange[1]; rowIdx++) { context.setRow(rowIdx); for (colIdx = colRange[0]; colIdx <= colRange[1]; colIdx++) { context.setColumn(colIdx); if (fn.call(scope || me, context, colIdx, rowIdx) === false) { return; } } } }, getFirstRowIndex: function() { return this.startCell ? Math.min(this.startCell.rowIdx, this.endCell.rowIdx) : 0; }, getLastRowIndex: function() { return this.startCell ? Math.max(this.startCell.rowIdx, this.endCell.rowIdx) : -1; }, getFirstColumnIndex: function() { return this.startCell ? Math.min(this.startCell.colIdx, this.endCell.colIdx) : 0; }, getLastColumnIndex: function() { return this.startCell ? Math.max(this.startCell.colIdx, this.endCell.colIdx) : -1; }, privates: { clear: function() { var me = this, view = me.view; me.eachCell(function(cellContext) { view.onCellDeselect(cellContext); }); me.startCell = me.endCell = null; }, setRangeStart: function(startCell) { this.startCell = (this.endCell = startCell.clone()).clone(); this.view.onCellSelect(startCell); }, setRangeEnd: function(endCell) { var me = this, range, lastRange, rowStart, rowEnd, colStart, colEnd, rowIdx, colIdx, view = me.view, rows = view.all, cell = new Ext.grid.CellContext(view), maxColIdx = view.getVisibleColumnManager().getColumns().length - 1; me.endCell = endCell.clone(); range = me.getRange(); lastRange = me.lastRange || range; rowStart = Math.max(Math.min(range[0][1], lastRange[0][1]), rows.startIndex); rowEnd = Math.min(Math.max(range[1][1], lastRange[1][1]), rows.endIndex); colStart = Math.min(range[0][0], lastRange[0][0]); colEnd = Math.min(Math.max(range[1][0], lastRange[1][0]), maxColIdx); for (rowIdx = rowStart; rowIdx <= rowEnd; rowIdx++) { for (colIdx = colStart; colIdx <= colEnd; colIdx++) { cell.setPosition(rowIdx, colIdx); if (rowIdx < range[0][1] || rowIdx > range[1][1] || colIdx < range[0][0] || colIdx > range[1][0]) { view.onCellDeselect(cell); } else { view.onCellSelect(cell); } } } me.lastRange = range; }, getRange: function() { return [ [ this.getFirstColumnIndex(), this.getFirstRowIndex() ], [ this.getLastColumnIndex(), this.getLastRowIndex() ] ]; }, getRangeSize: function() { return this.getCount(); }, getCount: function() { var range = this.getRange(); return (range[1][0] - range[0][0] + 1) * (range[1][1] - range[0][1] + 1); }, selectAll: function() { var me = this, view = me.view; me.clear(); me.setRangeStart(new Ext.grid.CellContext(view).setPosition(0, 0)); me.setRangeEnd(new Ext.grid.CellContext(view).setPosition(view.dataSource.getCount() - 1, view.getVisibleColumnManager().getColumns().length - 1)); }, isAllSelected: function() { var start = this.rangeStart, end = this.rangeEnd; if (start) { if (!start.colIdx && !start.rowIdx) { return end.colIdx === end.view.getVisibleColumnManager().getColumns().length - 1 && end.rowIdx === end.view.dataSource.getCount - 1; } } return false; }, getColumnRange: function() { return [ this.getFirstColumnIndex(), this.getLastColumnIndex() ]; }, getRowRange: function() { return [ this.getFirstRowIndex(), this.getLastRowIndex() ]; } } }); Ext.define('Ext.grid.selection.Columns', { extend: 'Ext.grid.selection.Selection', type: 'columns', isColumns: true, clone: function() { var me = this, result = new me.self(me.view), columns = me.selectedColumns; if (columns) { result.selectedColumns = Ext.Array.slice(columns); } return result; }, eachRow: function(fn, scope) { var columns = this.selectedColumns; if (columns && columns.length) { this.view.dataSource.each(fn, scope || this); } }, eachColumn: function(fn, scope) { var me = this, view = me.view, columns = me.selectedColumns, len, i, context = new Ext.grid.CellContext(view); if (columns) { len = columns.length; for (i = 0; i < len; i++) { context.setColumn(columns[i]); if (fn.call(scope || me, context.column, context.colIdx) === false) { return false; } } } }, eachCell: function(fn, scope) { var me = this, view = me.view, columns = me.selectedColumns, len, i, context = new Ext.grid.CellContext(view); if (columns) { len = columns.length; view.dataSource.each(function(record) { context.setRow(record); for (i = 0; i < len; i++) { context.setColumn(columns[i]); if (fn.call(scope || me, context, context.colIdx, context.rowIdx) === false) { return false; } } }); } }, contains: function(column) { var selectedColumns = this.selectedColumns; if (column && column.isColumn && selectedColumns && selectedColumns.length) { return Ext.Array.contains(selectedColumns, column); } return false; }, getCount: function() { var selectedColumns = this.selectedColumns; return selectedColumns ? selectedColumns.length : 0; }, getColumns: function() { return this.selectedColumns || []; }, privates: { add: function(column) { if (!column.isColumn) { Ext.Error.raise('Column selection must be passed a grid Column header object'); } Ext.Array.include((this.selectedColumns || (this.selectedColumns = [])), column); this.refreshColumns(column); }, clear: function() { var me = this, prevSelection = me.selectedColumns; if (prevSelection && prevSelection.length) { me.selectedColumns = []; me.refreshColumns.apply(me, prevSelection); } }, isAllSelected: function() { var selectedColumns = this.selectedColumns; return selectedColumns && selectedColumns.length === this.view.ownerGrid.getVisibleColumnManager().getColumns().length; }, refreshColumns: function(column) { var me = this, view = me.view, rows = view.all, rowIdx, columns = arguments, len = columns.length, colIdx, cellContext = new Ext.grid.CellContext(view), selected = []; if (view.rendered) { for (colIdx = 0; colIdx < len; colIdx++) { selected[colIdx] = me.contains(columns[colIdx]); } for (rowIdx = rows.startIndex; rowIdx <= rows.endIndex; rowIdx++) { cellContext.setRow(rowIdx); for (colIdx = 0; colIdx < len; colIdx++) { cellContext.setColumn(columns[colIdx]); if (selected[colIdx]) { view.onCellSelect(cellContext); } else { view.onCellDeselect(cellContext); } } } } }, remove: function(column) { if (!column.isColumn) { Ext.Error.raise('Column selection must be passed a grid Column header object'); } if (this.selectedColumns) { Ext.Array.remove(this.selectedColumns, column); this.refreshColumns(column); } }, selectAll: function() { var me = this; me.clear(); me.selectedColumns = me.view.getVisibleColumnManager().getColumns(); me.refreshColumns.apply(me, me.selectedColumns); } } }); Ext.define('Ext.grid.selection.Rows', { extend: 'Ext.grid.selection.Selection', requires: [ 'Ext.util.Collection' ], type: 'rows', isRows: true, clone: function() { var me = this, result = new me.self(me.view); if (me.selectedRecords) { result.selectedRecords = me.selectedRecords.clone(); } if (me.rangeStart) { result.setRangeStart(me.rangeStart); result.setRangeEnd(me.rangeEnd); } return result; }, add: function(record) { if (!(record.isModel)) { Ext.Error.raise('Row selection must be passed a record'); } var selection = this.selectedRecords || (this.selectedRecords = this.createRecordCollection()); if (!selection.byInternalId.get(record.internalId)) { selection.add(record); this.view.onRowSelect(record); } }, remove: function(record) { if (!(record.isModel)) { Ext.Error.raise('Row selection must be passed a record'); } var me = this; if (me.selectedRecords && me.selectedRecords.byInternalId.get(record.internalId)) { me.selectedRecords.remove(record); me.view.onRowDeselect(record); me.allSelected = false; return true; } }, contains: function(record) { if (!record || !record.isModel) { return false; } var me = this, result = false, selectedRecords = me.selectedRecords, recIndex, dragRange; if (me.allSelected) { me.add(record); return true; } if (selectedRecords) { result = !!selectedRecords.byInternalId.get(record.internalId); } if (!result && me.rangeStart != null) { dragRange = me.getRange(); recIndex = me.view.dataSource.indexOf(record); result = recIndex >= dragRange[0] && recIndex <= dragRange[1]; } return result; }, getCount: function() { var me = this, selectedRecords = me.selectedRecords, result = selectedRecords ? selectedRecords.getCount() : 0, range = me.getRange(), i, store = me.view.dataSource; for (i = range[0]; i <= range[1]; i++) { if (!selectedRecords || !selectedRecords.byInternalId.get(store.getAt(i).internalId)) { result++; } } return result; }, getRecords: function() { var selectedRecords = this.selectedRecords; return selectedRecords ? selectedRecords.getRange() : []; }, selectAll: function() { var me = this; me.clear(); me.setRangeStart(0); me.setRangeEnd(me.view.dataSource.getCount() - 1); me.addRange(); me.allSelected = true; }, eachRow: function(fn, scope) { var selectedRecords = this.selectedRecords; if (selectedRecords) { selectedRecords.each(fn, scope || this); } }, eachColumn: function(fn, scope) { var columns = this.view.getVisibleColumnManager().getColumns(), len = columns.length, i; if (this.selectedRecords) { for (i = 0; i < len; i++) { if (fn.call(this || scope, columns[i], i) === false) { return; } } } }, eachCell: function(fn, scope) { var me = this, selection = me.selectedRecords, view = me.view, columns = view.ownerGrid.getVisibleColumnManager().getColumns(), colCount, i, j, context, range, recCount, abort = false; if (columns) { colCount = columns.length; context = new Ext.grid.CellContext(view); if (selection) { selection.each(function(record) { context.setRow(record); for (i = 0; i < colCount; i++) { context.setColumn(columns[i]); if (fn.call(scope || me, context, context.colIdx, context.rowIdx) === false) { abort = true; return false; } } }); } if (!abort && me.rangeStart != null) { range = me.getRange(); me.view.dataSource.getRange(range[0], range[1], { callback: function(records) { recCount = records.length; for (i = 0; !abort && i < recCount; i++) { context.setRow(records[i]); for (j = 0; !abort && j < colCount; j++) { context.setColumn(columns[j]); if (fn.call(scope || me, context, context.colIdx, context.rowIdx) === false) { abort = true; } } } } }); } } }, beginUpdate: function() { var selectedRecords = this.selectedRecords; if (selectedRecords) { selectedRecords.beginUpdate(); } }, endUpdate: function() { var selectedRecords = this.selectedRecords; if (selectedRecords) { selectedRecords.endUpdate(); } }, destroy: function() { this.selectedRecords = Ext.destroy(this.selectedRecords); }, privates: { clear: function() { var me = this, view = me.view; me.allSelected = false; if (me.selectedRecords) { me.eachRow(function(record) { view.onRowDeselect(record); }); me.selectedRecords.clear(); } }, isAllSelected: function() { return !!this.allSelected; }, setRangeStart: function(start) { this.allSelected = false; this.rangeStart = this.rangeEnd = start; this.view.onRowSelect(start); }, setRangeEnd: function(end) { var me = this, range, lastRange, rowIdx, row, view = me.view, store = view.dataSource, rows = view.all, selected = me.selectedRecords, rec; me.rangeEnd = end; range = me.getRange(); lastRange = me.lastRange || range; for (rowIdx = Math.max(Math.min(range[0], lastRange[0]), rows.startIndex) , end = Math.min(Math.max(range[1], lastRange[1]), rows.endIndex); rowIdx <= end; rowIdx++) { row = rows.item(rowIdx); if (rowIdx < range[0] || rowIdx > range[1]) { if (selected && (rec = selected.byInternalId.get(store.getAt(rowIdx).internalId))) { selected.remove(rec); } view.onRowDeselect(rowIdx); } else { view.onRowSelect(rowIdx); } } me.lastRange = range; }, getRange: function() { var start = this.rangeStart, end = this.rangeEnd; if (start == null) { return [ 0, -1 ]; } else if (start <= end) { return [ start, end ]; } return [ end, start ]; }, getRangeSize: function() { var range = this.getRange(); return range[1] - range[0] + 1; }, createRecordCollection: function() { var result = new Ext.util.Collection({ rootProperty: 'data', extraKeys: { byInternalId: { rootProperty: false, property: 'internalId' } } }); return result; }, addRange: function() { var me = this, range, selection; if (me.rangeStart != null) { range = me.getRange(); selection = me.selectedRecords || (me.selectedRecords = me.createRecordCollection()); me.view.dataSource.getRange(range[0], range[1], { callback: function(range) { selection.add.apply(selection, range); } }); me.setRangeStart(me.lastRange = null); } } } }); Ext.define('Ext.grid.selection.SpreadsheetModel', { extend: 'Ext.selection.Model', requires: [ 'Ext.grid.selection.Selection', 'Ext.grid.selection.Cells', 'Ext.grid.selection.Rows', 'Ext.grid.selection.Columns' ], alias: 'selection.spreadsheet', isSpreadsheetModel: true, config: { columnSelect: { $value: false, lazy: true }, cellSelect: { $value: true, lazy: true }, rowSelect: { $value: true, lazy: true }, dragSelect: { $value: true, lazy: true }, selected: null }, checkboxSelect: false, checkboxColumnIndex: 0, showHeaderCheckbox: true, checkboxHeaderWidth: 24, rowNumbererHeaderWidth: 46, columnSelectCls: Ext.baseCSSPrefix + 'ssm-column-select', rowNumbererHeaderCls: Ext.baseCSSPrefix + 'ssm-row-numberer-hd', rowNumbererTdCls: Ext.grid.column.RowNumberer.prototype.tdCls + ' ' + Ext.baseCSSPrefix + 'ssm-row-numberer-cell', checkerOnCls: Ext.baseCSSPrefix + 'grid-hd-checker-on', tdCls: Ext.baseCSSPrefix + 'grid-cell-special ' + Ext.baseCSSPrefix + 'grid-cell-row-checker', bindComponent: function(view) { var me = this, viewListeners, lockedGrid; if (me.view !== view) { if (me.view) { me.navigationModel = null; Ext.destroy(me.viewListeners, me.navigationListeners); } me.view = view; if (view) { me.getCellSelect(); lockedGrid = view.ownerGrid.lockedGrid; if (lockedGrid) { me.hasLockedHeader = true; me.onViewCreated(lockedGrid, lockedGrid.getView()); } else { view.grid.on({ viewcreated: me.onViewCreated, scope: me, single: true }); } me.gridListeners = view.ownerGrid.on({ columnschanged: me.onColumnsChanged, scope: me, destroyable: true }); viewListeners = me.getViewListeners(); viewListeners.scope = me; viewListeners.destroyable = true; me.viewListeners = view.on(viewListeners); me.navigationModel = view.getNavigationModel(); me.navigationListeners = me.navigationModel.on({ navigate: me.onNavigate, scope: me, destroyable: true }); if (me.getColumnSelect()) { view.ownerGrid.addCls(me.columnSelectCls); } } } }, getCheckboxHeaderConfig: function() { var me = this, showCheck = me.showHeaderCheckbox !== false; return { isCheckerHd: showCheck, text: ' ', clickTargetName: 'el', width: me.checkboxHeaderWidth, sortable: false, draggable: false, resizable: false, hideable: false, menuDisabled: true, dataIndex: '', tdCls: me.tdCls, cls: showCheck ? Ext.baseCSSPrefix + 'column-header-checkbox ' : '', defaultRenderer: me.checkboxRenderer.bind(me), editRenderer: ' ', locked: me.hasLockedHeader }; }, checkboxRenderer: function() { return ''; }, onHeaderClick: function(headerCt, header, e) { var me = this, sel = me.selected; if (header === me.numbererColumn || header === me.checkColumn) { e.stopEvent(); if (!sel || !sel.isAllSelected()) { me.selectAll(headerCt.view); } else { me.deselectAll(); } me.updateHeaderState(); } else if (me.columnSelect) { if (me.isColumnSelected(header)) { me.deselectColumn(header); } else { me.selectColumn(header, e.ctrlKey); } } }, updateHeaderState: function() { var me = this, store = me.view.dataSource, storeCount = store.getCount(), views = me.views, sel = me.selected, isChecked = sel && sel.isRows && !store.isBufferedStore && storeCount > 0 && (storeCount === sel.getCount()), checkHd = me.checkColumn, cls = me.checkerOnCls; if (views && views.length) { if (checkHd) { if (isChecked) { checkHd.addCls(cls); } else { checkHd.removeCls(cls); } } } }, onReconfigure: function(grid, store, columns) { if (columns) { this.addCheckbox(this.views[0]); } }, getCellContext: function(record, column) { return new Ext.grid.CellContext(this.view.ownerGrid.getView()).setPosition(record, column); }, select: function(records, keepExisting, suppressEvent) { var me = this, sel = me.selected, view = me.view, store = view.dataSource, len, i, record, changed = false; if (!sel || !sel.isRows || sel.view !== view) { me.resetSelection(true); sel = me.selected = new Ext.grid.selection.Rows(view); } else if (!keepExisting) { sel.clear(); } if (!Ext.isArray(records)) { records = [ records ]; } len = records.length; for (i = 0; i < len; i++) { record = records[i]; if (typeof record === 'number') { record = store.getAt(record); } if (!sel.contains(record)) { sel.add(record); changed = true; } } if (changed) { me.updateHeaderState(); if (suppressEvent) { me.fireSelectionChange(); } } }, deselect: function(records, suppressEvent) { var me = this, sel = me.selected, store = me.view.dataSource, len, i, record, changed = false; if (sel && sel.isRows) { if (!Ext.isArray(records)) { records = [ records ]; } len = records.length; for (i = 0; i < len; i++) { record = records[i]; if (typeof record === 'number') { record = store.getAt(record); } changed = changed || sel.remove(record); } } if (changed) { me.updateHeaderState(); if (!suppressEvent) { me.fireSelectionChange(); } } }, selectCells: function(rangeStart, rangeEnd, suppressEvent) { var me = this, view = me.view.ownerGrid.view, sel; rangeStart = rangeStart.isCellContext ? rangeStart.clone() : new Ext.grid.CellContext(view).setPosition(rangeStart); rangeEnd = rangeEnd.isCellContext ? rangeEnd.clone() : new Ext.grid.CellContext(view).setPosition(rangeEnd); me.resetSelection(true); me.selected = sel = new Ext.grid.selection.Cells(rangeStart.view); sel.setRangeStart(rangeStart); sel.setRangeEnd(rangeEnd); if (!suppressEvent) { me.fireSelectionChange(); } }, selectAll: function(suppressEvent) { var me = this, sel = me.selected, doSelect, view = me.view; if (me.rowSelect) { if (!sel || !sel.isRows) { me.resetSelection(true); me.selected = sel = new Ext.grid.selection.Rows(view); } doSelect = true; } else if (me.cellSelect) { if (!sel || !sel.isCells) { me.resetSelection(true); me.selected = sel = new Ext.grid.selection.Cells(view); } doSelect = true; } else if (me.columnSelect) { if (!sel || !sel.isColumns) { me.resetSelection(true); me.selected = sel = new Ext.grid.selection.Columns(view); } doSelect = true; } if (doSelect) { sel.selectAll(); me.updateHeaderState(); if (!suppressEvent) { me.fireSelectionChange(); } } }, deselectAll: function(suppressEvent) { var sel = this.selected; if (sel && sel.getCount()) { sel.clear(); if (!suppressEvent) { this.fireSelectionChange(); } } }, selectRows: function(rows, keepSelection, suppressEvent) { var me = this, sel = me.selected, isSelectingRows = sel && !sel.isRows, len = rows.length, i; if (!keepSelection || isSelectingRows) { me.resetSelection(true); } if (!isSelectingRows) { me.selected = sel = new Ext.grid.selection.Rows(me.view); } for (i = 0; i < len; i++) { sel.add(rows[i]); } if (!suppressEvent) { me.fireSelectionChange(); } }, isSelected: function(record) { return this.isRowSelected(record); }, selectColumn: function(column, keepSelection, suppressEvent) { var me = this, selData = me.selected, view = column.getView(); if (!selData || !selData.isColumns || selData.view !== view.ownerGrid.view) { me.resetSelection(true); me.selected = selData = new Ext.grid.selection.Columns(view); } if (!selData.contains(column)) { if (!keepSelection) { selData.clear(); } selData.add(column); me.updateHeaderState(); if (!suppressEvent) { me.fireSelectionChange(); } } }, deselectColumn: function(column, suppressEvent) { var me = this, selData = me.getSelected(); if (selData && selData.isColumns && selData.contains(column)) { selData.remove(column); me.updateHeaderState(); if (!suppressEvent) { me.fireSelectionChange(); } } }, getSelection: function() { var selData = this.selected; if (selData && selData.isRows) { return selData.getRecords(); } return []; }, destroy: function() { var me = this, scrollEls = me.scrollEls; Ext.destroy(me.gridListeners, me.viewListeners, me.selected, me.navigationListeners); if (scrollEls) { Ext.dd.ScrollManager.unregister(scrollEls); } me.selected = me.gridListeners = me.viewListeners = me.selectionData = me.navigationListeners = me.scrollEls = null; me.callParent(); }, privates: { getViewListeners: function() { return { beforerefresh: this.onBeforeViewRefresh, keyup: { element: 'el', fn: this.onViewKeyUp, scope: this } }; }, onViewKeyUp: function(e) { var sel = this.selected; if (e.keyCode === e.SHIFT && sel && sel.isRows && sel.getRangeSize()) { sel.addRange(); } }, onColumnsChanged: function() { var selData = this.selected, rowRange, colCount, colIdx, rowIdx, view, context; if (selData && selData.isCells) { view = selData.view; context = new Ext.grid.CellContext(view); rowRange = selData.getRowRange(); colCount = view.getVisibleColumnManager().getColumns().length; for (rowIdx = rowRange[0]; rowIdx <= rowRange[1]; rowIdx++) { context.setRow(rowIdx); for (colIdx = 0; colIdx < colCount; colIdx++) { context.setColumn(colIdx); view.onCellDeselect(context); } } } }, onBeforeViewRefresh: function(view) { var selData = this.selected; if (view.refreshCounter) { if (selData && selData.isCells) { this.resetSelection(); } } }, resetSelection: function(suppressEvent) { var sel = this.selected; if (sel) { sel.clear(); if (!suppressEvent) { this.fireSelectionChange(); } } }, onViewCreated: function(grid, view) { var me = this, ownerGrid = view.ownerGrid, headerCt = view.headerCt, shrinkwrapLocked = ownerGrid.shrinkWrapLocked; if (!ownerGrid.lockable || view.isLockedView) { if (me.getRowSelect() && !headerCt.down('rownumberer')) { me.numbererColumn = headerCt.add(0, { xtype: 'rownumberer', width: me.rowNumbererHeaderWidth, editRenderer: ' ', tdCls: me.rowNumbererTdCls, cls: me.rowNumbererHeaderCls, locked: me.hasLockedHeader }); if (shrinkwrapLocked) { grid.width += me.numbererColumn.width; } } if (me.checkboxSelect) { me.addCheckbox(view, true); me.mon(view.ownerGrid, 'reconfigure', me.onReconfigure, me); if (shrinkwrapLocked) { grid.width += me.checkColumn.width; } } } headerCt.sortOnClick = !me.getColumnSelect(); if (me.getDragSelect()) { view.on('render', me.onViewRender, me, { single: true }); } }, onViewRender: function(view) { var me = this, el = view.getEl(); el.ddScrollConfig = { vthresh: 50, hthresh: 50, frequency: 300, increment: 100 }; Ext.dd.ScrollManager.register(el); (me.scrollEls || (me.scrollEls = [])).push(el); view.on('cellmousedown', me.handleMouseDown, me); if (view.lockingPartner) { view.lockingPartner.on('cellmousedown', me.handleMouseDown, me); } }, handleMouseDown: function(view, td, cellIndex, record, tr, rowIdx, e) { var me = this, sel = me.selected, header = e.position.column, isCheckClick, startDragSelect; if (e.button || e.shiftKey || e.altKey || e.pointerType === 'touch') { return; } if (header) { isCheckClick = header === me.checkColumn; if (header === me.numbererColumn || isCheckClick || !me.cellSelect) { if (me.rowSelect) { if (sel && sel.isRows) { if (!e.ctrlKey && !isCheckClick) { sel.clear(); } } else { if (sel) { sel.clear(); } sel = me.selected = new Ext.grid.selection.Rows(view); } startDragSelect = true; } } else { if (sel) { sel.clear(); } if (!sel || !sel.isCells) { sel = me.selected = new Ext.grid.selection.Cells(view); } startDragSelect = true; } me.lastOverRecord = me.lastOverColumn = null; Ext.getBody().on('mouseup', me.onMouseUp, me, { single: true, view: sel.view }); if (startDragSelect) { sel.view.el.on('mousemove', me.onMouseMove, me, { view: sel.view }); } } }, onMouseMove: function(e, target, opts) { var me = this, view = opts.view, record, rowIdx, cell = e.getTarget(view.cellSelector), header = opts.view.getHeaderByCell(cell), selData = me.selected, pos, recChange, colChange; if (header) { record = view.getRecord(cell.parentNode); rowIdx = me.store.indexOf(record); recChange = record !== me.lastOverRecord; colChange = header !== me.lastOverColumn; if (recChange || colChange) { pos = me.getCellContext(record, header); } if (selData.isRows) { if (recChange) { if (me.lastOverRecord) { selData.setRangeEnd(rowIdx); } else { selData.setRangeStart(rowIdx); } } } else { if (recChange || colChange) { if (me.lastOverRecord) { selData.setRangeEnd(pos); } else { selData.setRangeStart(pos); } } } if (recChange || colChange) { view.getNavigationModel().setPosition(new Ext.grid.CellContext(header.getView()).setPosition(record, header)); } me.lastOverColumn = header; me.lastOverRecord = record; } }, onMouseUp: function(e, target, opts) { var me = this, view = opts.view; if (view && !view.isDestroyed) { view.el.un('mousemove', me.onMouseMove, me); if (me.selected.isRows) { me.selected.addRange(); } me.fireSelectionChange(); } }, addCheckbox: function(view, initial) { var me = this, checkbox = me.checkboxColumnIndex, headerCt = view.headerCt; if (checkbox !== false) { if (checkbox === 'first') { checkbox = 0; } else if (checkbox === 'last') { checkbox = headerCt.getColumnCount(); } me.checkColumn = headerCt.add(checkbox, me.getCheckboxHeaderConfig()); } if (initial !== true) { view.refresh(); } }, onNavigate: function(navigateEvent) { var me = this, view = navigateEvent.view.ownerGrid.view, record = navigateEvent.record, sel = me.selected, pos = new Ext.grid.CellContext(view).setPosition(record, navigateEvent.column), keyEvent = navigateEvent.keyEvent, keyCode = keyEvent.getKey(), selectionChanged; if (keyEvent.ctrlKey && (keyCode === keyEvent.UP || keyCode === keyEvent.LEFT || keyCode === keyEvent.RIGHT || keyCode === keyEvent.DOWN)) { return; } if (sel && sel.isCells && sel.getCount() > 1 && keyEvent.type === 'click') { return; } if (!(me.cellSelect || me.columnSelect || me.rowSelect) || !navigateEvent.record || keyEvent.type === 'mousedown') { return; } if (keyEvent.ctrlKey && keyEvent.keyCode === keyEvent.A) { if (!sel || sel.getCount() < 2) { me.selectAll(); } else { me.deselectAll(); } me.updateHeaderState(); return; } if (keyEvent.shiftKey) { if (pos.column === me.numbererColumn || pos.column === me.checkColumn || !me.cellSelect || (sel && sel.isRows)) { if (me.rowSelect) { if (!sel || !sel.isRows || sel.view !== view) { me.resetSelection(true); sel = me.selected = new Ext.grid.selection.Rows(view); } if (!sel.getRangeSize()) { sel.setRangeStart(navigateEvent.previousRecordIndex || 0); } sel.setRangeEnd(navigateEvent.recordIndex); selectionChanged = true; } } else { if (me.cellSelect) { if (!sel || !sel.isCells || sel.view !== view) { me.resetSelection(true); sel = me.selected = new Ext.grid.selection.Cells(view); } if (!sel.getRangeSize()) { sel.setRangeStart(navigateEvent.previousPosition || me.getCellContext(0, 0)); } sel.setRangeEnd(pos); selectionChanged = true; } } } else { if (pos.column === me.numbererColumn || pos.column === me.checkColumn || !me.cellSelect) { if (me.rowSelect) { if (!sel || !sel.isRows || sel.view !== view) { me.resetSelection(true); sel = me.selected = new Ext.grid.selection.Rows(view); } if (keyEvent.ctrlKey || pos.column === me.checkColumn) { if (sel.contains(record)) { sel.remove(record); } else { sel.add(record); } } else { sel.clear(); sel.add(record); } selectionChanged = true; } } else { if (me.cellSelect) { if (!sel || !sel.isCells || sel.view !== view) { me.resetSelection(true); me.selected = sel = new Ext.grid.selection.Cells(view); } else { sel.clear(); } sel.setRangeStart(pos); selectionChanged = true; } } } if (selectionChanged) { if (sel.isRows) { me.updateHeaderState(); } me.fireSelectionChange(); } }, isRowSelected: function(record) { var me = this, sel = me.selected; if (sel && sel.isRows) { record = Ext.isNumber(record) ? me.store.getAt(record) : record; return sel.contains(record); } else { return false; } }, isColumnSelected: function(column) { var me = this, sel = me.selected; if (sel && sel.isColumns) { return sel.contains(column); } else { return false; } }, isCellSelected: function(view, row, column) { var me = this, testPos, sel = me.selected; view = view.ownerGrid.view; if (sel) { if (sel.isColumns) { if (typeof column === 'number') { column = view.getVisibleColumnManager().getColumns()[column]; } return sel.contains(column); } if (sel.isCells) { testPos = new Ext.grid.CellContext(view).setPosition({ row: row, column: column }); return sel.contains(testPos); } } return false; }, applySelected: function(selected) { if (selected && !(selected.isRows || selected.isCells || selected.isColumns)) { Ext.error.raise('SpreadsheelModel#setSelected must be passed an instance of Ext.grid.selection.Selection'); } return selected; }, updateSelected: function(selected, oldSelected) { var view, columns, len, i, cell; if (oldSelected) { oldSelected.clear(); } if (selected && selected.getCount()) { view = selected.view; if (selected.isRows) { selected.eachRow(view.onRowSelect, view); } else if (selected.isColumns) { columns = selected.getColumns(); len = columns.length; if (len) { cell = new Ext.grid.CelContext(view); view.store.each(function(rec) { cell.setRow(rec); for (i = 0; i < len; i++) { cell.setColumn(columns[i]); view.onCellSelect(cell); } }); } } else if (selected.isCells) { selected.eachCell(view.onCellSelect, view); } } }, updateRowSelect: function(rowSelect) { var me = this, sel = me.selected, view = me.view; if (view && view.rendered) { if (view.isNormalView) { view = view.lockingPartner; } if (rowSelect) { if (me.checkColumn) { me.checkColumn.show(); } if (me.numbererColumn) { me.numbererColumn.show(); } else { me.numbererColumn = view.headerCt.add(0, { xtype: 'rownumberer', width: me.rowNumbererHeaderWidth, editRenderer: ' ', tdCls: me.rowNumbererTdCls, cls: me.rowNumbererHeaderCls, locked: me.hasLockedHeader }); } } else { if (me.checkColumn) { me.checkColumn.hide(); } if (me.numbererColumn) { me.numbererColumn.hide(); } } if (!rowSelect && sel && sel.isRows) { sel.clear(); me.fireSelectionChange(); } } }, updateColumnSelect: function(columnSelect) { var me = this, sel = me.selected, views = me.views, len = views ? views.length : 0, i; for (i = 0; i < len; i++) { views[i].headerCt.sortOnClick = !columnSelect; } if (!columnSelect && sel && sel.isColumns) { sel.clear(); me.fireSelectionChange(); } if (columnSelect) { me.view.ownerGrid.addCls(me.columnSelectCls); } else { me.view.ownerGrid.removeCls(me.columnSelectCls); } }, updateCellSelect: function(cellSelect) { var me = this, sel = me.selected; if (!cellSelect && sel && sel.isCells) { sel.clear(); me.fireSelectionChange(); } }, fireSelectionChange: function() { var grid = this.view.ownerGrid; grid.fireEvent('selectionchange', grid, this.selected); }, onIdChanged: function(store, rec, oldId, newId) { var sel = this.selected; if (sel && sel.isRows && sel.selectedRecords) { sel.selectedRecords.updateKey(rec, oldId); } }, onPageAdd: function(pageMap, pageNumber, records) { var sel = this.selected, len = records.length, i, record, selected = sel && sel.selectedRecords; if (selected && sel.isRows) { for (i = 0; i < len; i++) { record = records[i]; if (selected.get(record.id)) { selected.replace(record); } } } }, refresh: function() { var sel = this.getSelected(); if (sel && sel.isRows) { this.callParent(); } }, onStoreAdd: function() { var sel = this.getSelected(); if (sel && sel.isRows) { this.callParent(arguments); this.updateHeaderState(); } }, onStoreClear: function() { this.resetSelection(); }, onStoreLoad: function() { var sel = this.getSelected(); if (sel && sel.isRows) { this.callParent(arguments); this.updateHeaderState(); } }, onStoreRefresh: function() { var sel = this.selected; if (sel && sel.isRows && sel.selectedRecords) { this.updateSelectedInstances(sel.selectedRecords); } this.updateHeaderState(); }, onStoreRemove: function() { var sel = this.getSelected(); if (sel && sel.isRows) { this.callParent(arguments); } } } }); Ext.define('Ext.util.Queue', { constructor: function() { this.clear(); }, add: function(obj) { var me = this, key = me.getKey(obj); if (!me.map[key]) { ++me.length; me.items.push(obj); me.map[key] = obj; } return obj; }, clear: function() { var me = this, items = me.items; me.items = []; me.map = {}; me.length = 0; return items; }, contains: function(obj) { var key = this.getKey(obj); return this.map.hasOwnProperty(key); }, getCount: function() { return this.length; }, getKey: function(obj) { return obj.id; }, remove: function(obj) { var me = this, key = me.getKey(obj), items = me.items, index; if (me.map[key]) { index = Ext.Array.indexOf(items, obj); Ext.Array.erase(items, index, 1); delete me.map[key]; --me.length; } return obj; } }); Ext.define('Ext.layout.ContextItem', { heightModel: null, widthModel: null, sizeModel: null, optOut: false, ownerSizePolicy: null, boxChildren: null, boxParent: null, children: [], dirty: null, dirtyCount: 0, hasRawContent: true, isContextItem: true, isTopLevel: false, consumersContentHeight: 0, consumersContentWidth: 0, consumersContainerHeight: 0, consumersContainerWidth: 0, consumersHeight: 0, consumersWidth: 0, ownerCtContext: null, remainingChildDimensions: 0, props: null, state: null, wrapsComponent: false, constructor: function(config) { var me = this, sizeModels = Ext.layout.SizeModel.sizeModels, configured = sizeModels.configured, shrinkWrap = sizeModels.shrinkWrap, el, lastBox, ownerCt, ownerCtContext, props, sizeModel, target, lastWidth, lastHeight, sameWidth, sameHeight, widthModel, heightModel, optOut; Ext.apply(me, config); target = me.target; el = me.el; me.id = target.id; me.flushedProps = {}; me.props = props = {}; me.styles = {}; if (!target.isComponent) { lastBox = el.lastBox; } else { me.wrapsComponent = true; me.framing = target.frameSize || null; me.isComponentChild = target.ownerLayout && target.ownerLayout.isComponentLayout; lastBox = target.lastBox; ownerCt = target.ownerCt; if (ownerCt && (ownerCtContext = ownerCt.el && me.context.items[ownerCt.el.id])) { me.ownerCtContext = ownerCtContext; } me.sizeModel = sizeModel = target.getSizeModel(ownerCtContext && ownerCtContext.widthModel.pairsByHeightOrdinal[ownerCtContext.heightModel.ordinal]); me.widthModel = widthModel = sizeModel.width; me.heightModel = heightModel = sizeModel.height; if (lastBox && lastBox.invalid === false) { sameWidth = (target.width === (lastWidth = lastBox.width)); sameHeight = (target.height === (lastHeight = lastBox.height)); if (widthModel === shrinkWrap && heightModel === shrinkWrap) { optOut = true; } else if (widthModel === configured && sameWidth) { optOut = heightModel === shrinkWrap || (heightModel === configured && sameHeight); } if (optOut) { me.optOut = true; props.width = lastWidth; props.height = lastHeight; } } } me.lastBox = lastBox; }, init: function(full, options) { var me = this, oldProps = me.props, oldDirty = me.dirty, ownerCtContext = me.ownerCtContext, ownerLayout = me.target.ownerLayout, firstTime = !me.state, ret = full || firstTime, children, i, n, ownerCt, sizeModel, target, oldHeightModel = me.heightModel, oldWidthModel = me.widthModel, newHeightModel, newWidthModel, remainingCount = 0; me.dirty = me.invalid = false; me.props = {}; me.remainingChildDimensions = 0; if (me.boxChildren) { me.boxChildren.length = 0; } if (!firstTime) { me.clearAllBlocks('blocks'); me.clearAllBlocks('domBlocks'); } if (!me.wrapsComponent) { return ret; } target = me.target; me.state = {}; if (firstTime) { if (target.beforeLayout && target.beforeLayout !== Ext.emptyFn) { target.beforeLayout(); } if (!ownerCtContext && (ownerCt = target.ownerCt)) { ownerCtContext = me.context.items[ownerCt.el.id]; } if (ownerCtContext) { me.ownerCtContext = ownerCtContext; me.isBoxParent = ownerLayout && ownerLayout.isItemBoxParent(me); } else { me.isTopLevel = true; } me.frameBodyContext = me.getEl('frameBody'); } else { ownerCtContext = me.ownerCtContext; me.isTopLevel = !ownerCtContext; children = me.children; for (i = 0 , n = children.length; i < n; ++i) { children[i].init(true); } } me.hasRawContent = !(target.isContainer && target.items.items.length > 0); if (full) { me.widthModel = me.heightModel = null; sizeModel = target.getSizeModel(ownerCtContext && ownerCtContext.widthModel.pairsByHeightOrdinal[ownerCtContext.heightModel.ordinal]); if (firstTime) { me.sizeModel = sizeModel; } me.widthModel = sizeModel.width; me.heightModel = sizeModel.height; if (ownerCtContext && !me.isComponentChild) { if (ownerLayout.needsItemSize || !target.liquidLayout) { ownerCtContext.remainingChildDimensions += 2; } else { if (me.widthModel.calculated) { ++ownerCtContext.remainingChildDimensions; } if (me.heightModel.calculated) { ++ownerCtContext.remainingChildDimensions; } } } } else if (oldProps) { me.recoverProp('x', oldProps, oldDirty); me.recoverProp('y', oldProps, oldDirty); if (me.widthModel.calculated) { me.recoverProp('width', oldProps, oldDirty); } else if ('width' in oldProps) { ++remainingCount; } if (me.heightModel.calculated) { me.recoverProp('height', oldProps, oldDirty); } else if ('height' in oldProps) { ++remainingCount; } if (ownerCtContext && !me.isComponentChild) { ownerCtContext.remainingChildDimensions += remainingCount; } } if (oldProps && ownerLayout && ownerLayout.manageMargins) { me.recoverProp('margin-top', oldProps, oldDirty); me.recoverProp('margin-right', oldProps, oldDirty); me.recoverProp('margin-bottom', oldProps, oldDirty); me.recoverProp('margin-left', oldProps, oldDirty); } if (options) { newHeightModel = options.heightModel; newWidthModel = options.widthModel; if (newWidthModel && newHeightModel && oldWidthModel && oldHeightModel) { if (oldWidthModel.shrinkWrap && oldHeightModel.shrinkWrap) { if (newWidthModel.constrainedMax && newHeightModel.constrainedMin) { newHeightModel = null; } } } if (newWidthModel) { me.widthModel = newWidthModel; } if (newHeightModel) { me.heightModel = newHeightModel; } if (options.state) { Ext.apply(me.state, options.state); } } return ret; }, initContinue: function(full) { var me = this, ownerCtContext = me.ownerCtContext, comp = me.target, widthModel = me.widthModel, inheritedState = comp.getInherited(), boxParent; if (widthModel.fixed) { inheritedState.inShrinkWrapTable = false; } else { delete inheritedState.inShrinkWrapTable; } if (full) { if (ownerCtContext && widthModel.shrinkWrap) { boxParent = ownerCtContext.isBoxParent ? ownerCtContext : ownerCtContext.boxParent; if (boxParent) { boxParent.addBoxChild(me); } } else if (widthModel.natural) { me.boxParent = ownerCtContext; } } return full; }, initDone: function(containerLayoutDone) { var me = this, props = me.props, state = me.state; if (me.remainingChildDimensions === 0) { props.containerChildrenSizeDone = true; } if (containerLayoutDone) { props.containerLayoutDone = true; } if (me.boxChildren && me.boxChildren.length && me.widthModel.shrinkWrap) { me.el.setWidth(10000); state.blocks = (state.blocks || 0) + 1; } }, initAnimation: function() { var me = this, target = me.target, ownerCtContext = me.ownerCtContext; if (ownerCtContext && ownerCtContext.isTopLevel) { me.animatePolicy = target.ownerLayout.getAnimatePolicy(me); } else if (!ownerCtContext && target.isCollapsingOrExpanding && target.animCollapse) { me.animatePolicy = target.componentLayout.getAnimatePolicy(me); } if (me.animatePolicy) { me.context.queueAnimation(me); } }, addBlock: function(name, layout, propName) { var me = this, collection = me[name] || (me[name] = {}), blockedLayouts = collection[propName] || (collection[propName] = {}); if (!blockedLayouts[layout.id]) { blockedLayouts[layout.id] = layout; ++layout.blockCount; ++me.context.blockCount; } }, addBoxChild: function(boxChildItem) { var me = this, children, widthModel = boxChildItem.widthModel; boxChildItem.boxParent = this; boxChildItem.measuresBox = widthModel.shrinkWrap ? boxChildItem.hasRawContent : widthModel.natural; if (boxChildItem.measuresBox) { children = me.boxChildren; if (children) { children.push(boxChildItem); } else { me.boxChildren = [ boxChildItem ]; } } }, addPositionStyles: function(styles, props) { var x = props.x, y = props.y, count = 0; if (x !== undefined) { styles.left = x + 'px'; ++count; } if (y !== undefined) { styles.top = y + 'px'; ++count; } return count; }, addTrigger: function(propName, inDom) { var me = this, name = inDom ? 'domTriggers' : 'triggers', collection = me[name] || (me[name] = {}), context = me.context, layout = context.currentLayout, triggers = collection[propName] || (collection[propName] = {}); if (!triggers[layout.id]) { triggers[layout.id] = layout; ++layout.triggerCount; triggers = context.triggers[inDom ? 'dom' : 'data']; (triggers[layout.id] || (triggers[layout.id] = [])).push({ item: this, prop: propName }); if (me.props[propName] !== undefined) { if (!inDom || !(me.dirty && (propName in me.dirty))) { ++layout.firedTriggers; } } } }, boxChildMeasured: function() { var me = this, state = me.state, count = (state.boxesMeasured = (state.boxesMeasured || 0) + 1); if (count === me.boxChildren.length) { state.clearBoxWidth = 1; ++me.context.progressCount; me.markDirty(); } }, borderNames: [ 'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width' ], marginNames: [ 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ], paddingNames: [ 'padding-top', 'padding-right', 'padding-bottom', 'padding-left' ], trblNames: [ 'top', 'right', 'bottom', 'left' ], cacheMissHandlers: { borderInfo: function(me) { var info = me.getStyles(me.borderNames, me.trblNames); info.width = info.left + info.right; info.height = info.top + info.bottom; return info; }, marginInfo: function(me) { var info = me.getStyles(me.marginNames, me.trblNames); info.width = info.left + info.right; info.height = info.top + info.bottom; return info; }, paddingInfo: function(me) { var item = me.frameBodyContext || me, info = item.getStyles(me.paddingNames, me.trblNames); info.width = info.left + info.right; info.height = info.top + info.bottom; return info; } }, checkCache: function(entry) { return this.cacheMissHandlers[entry](this); }, clearAllBlocks: function(name) { var collection = this[name], propName; if (collection) { for (propName in collection) { this.clearBlocks(name, propName); } } }, clearBlocks: function(name, propName) { var collection = this[name], blockedLayouts = collection && collection[propName], context, layout, layoutId; if (blockedLayouts) { delete collection[propName]; context = this.context; for (layoutId in blockedLayouts) { layout = blockedLayouts[layoutId]; --context.blockCount; if (!--layout.blockCount && !layout.pending && !layout.done) { context.queueLayout(layout); } } } }, block: function(layout, propName) { this.addBlock('blocks', layout, propName); }, domBlock: function(layout, propName) { this.addBlock('domBlocks', layout, propName); }, fireTriggers: function(name, propName) { var collection = this[name], triggers = collection && collection[propName], context = this.context, layout, layoutId; if (triggers) { for (layoutId in triggers) { layout = triggers[layoutId]; ++layout.firedTriggers; if (!layout.done && !layout.blockCount && !layout.pending) { context.queueLayout(layout); } } } }, flush: function() { var me = this, dirty = me.dirty, state = me.state, targetEl = me.el; me.dirtyCount = 0; if ('attributes' in me) { targetEl.set(me.attributes); delete me.attributes; } if ('innerHTML' in me) { targetEl.innerHTML = me.innerHTML; delete me.innerHTML; } if (state && state.clearBoxWidth) { state.clearBoxWidth = 0; me.el.setStyle('width', null); if (!--state.blocks) { me.context.queueItemLayouts(me); } } if (dirty) { delete me.dirty; me.writeProps(dirty, true); } }, flushAnimations: function() { var me = this, animateFrom = me.previousSize, target, targetAnim, duration, animateProps, anim, changeCount, j, propsLen, propName, oldValue, newValue; if (animateFrom) { target = me.target; targetAnim = target.getAnimationProps(); duration = targetAnim.duration; animateProps = Ext.Object.getKeys(me.animatePolicy); anim = Ext.apply({}, { from: {}, to: {}, duration: duration || Ext.fx.Anim.prototype.duration }, targetAnim); for (changeCount = 0 , j = 0 , propsLen = animateProps.length; j < propsLen; j++) { propName = animateProps[j]; oldValue = animateFrom[propName]; newValue = me.peek(propName); if (oldValue !== newValue) { propName = me.translateProps[propName] || propName; anim.from[propName] = oldValue; anim.to[propName] = newValue; ++changeCount; } } if (changeCount) { if (me.isCollapsingOrExpanding === 1) { target.componentLayout.undoLayout(me); } else { me.writeProps(anim.from); } me.el.animate(anim); anim = Ext.fx.Manager.getFxQueue(me.el.id)[0]; target.$layoutAnim = anim; anim.on({ afteranimate: function() { delete target.$layoutAnim; if (me.isCollapsingOrExpanding === 1) { target.componentLayout.redoLayout(me); target.afterCollapse(true); } else if (me.isCollapsingOrExpanding === 2) { target.afterExpand(true); } } }); } } }, getBorderInfo: function() { var me = this, info = me.borderInfo; if (!info) { me.borderInfo = info = me.checkCache('borderInfo'); } return info; }, getEl: function(nameOrEl, owner) { var me = this, src, el, elContext; if (nameOrEl) { if (nameOrEl.dom) { el = nameOrEl; } else { src = me.target; if (owner) { src = owner; } el = src[nameOrEl]; if (typeof el === 'function') { el = el.call(src); if (el === me.el) { return this; } } } if (el) { elContext = me.context.getEl(me, el); } } return elContext || null; }, getFrameInfo: function() { var me = this, info = me.frameInfo, framing, border; if (!info) { framing = me.framing; border = me.getBorderInfo(); me.frameInfo = info = framing ? { top: framing.top + border.top, right: framing.right + border.right, bottom: framing.bottom + border.bottom, left: framing.left + border.left, width: framing.width + border.width, height: framing.height + border.height } : border; } return info; }, getMarginInfo: function() { var me = this, info = me.marginInfo, comp, manageMargins, ownerLayout, ownerLayoutId; if (!info) { if (!me.wrapsComponent) { info = me.checkCache('marginInfo'); } else { comp = me.target; ownerLayout = comp.ownerLayout; ownerLayoutId = ownerLayout ? ownerLayout.id : null; manageMargins = ownerLayout && ownerLayout.manageMargins; info = comp.margin$; if (info && info.ownerId !== ownerLayoutId) { info = null; } if (!info) { info = me.parseMargins(comp, comp.margin) || me.checkCache('marginInfo'); if (manageMargins) { me.setProp('margin-top', 0); me.setProp('margin-right', 0); me.setProp('margin-bottom', 0); me.setProp('margin-left', 0); } info.ownerId = ownerLayoutId; comp.margin$ = info; } info.width = info.left + info.right; info.height = info.top + info.bottom; } me.marginInfo = info; } return info; }, clearMarginCache: function() { delete this.marginInfo; delete this.target.margin$; }, getPaddingInfo: function() { var me = this, info = me.paddingInfo; if (!info) { me.paddingInfo = info = me.checkCache('paddingInfo'); } return info; }, getProp: function(propName) { var me = this, result = me.props[propName]; me.addTrigger(propName); return result; }, getDomProp: function(propName) { var me = this, result = (me.dirty && (propName in me.dirty)) ? undefined : me.props[propName]; me.addTrigger(propName, true); return result; }, getStyle: function(styleName) { var me = this, styles = me.styles, info, value; if (styleName in styles) { value = styles[styleName]; } else { info = me.styleInfo[styleName]; value = me.el.getStyle(styleName); if (info && info.parseInt) { value = parseInt(value, 10) || 0; } styles[styleName] = value; } return value; }, getStyles: function(styleNames, altNames) { var me = this, styleCache = me.styles, values = {}, hits = 0, n = styleNames.length, i, missing, missingAltNames, name, info, styleInfo, styles, value; altNames = altNames || styleNames; for (i = 0; i < n; ++i) { name = styleNames[i]; if (name in styleCache) { values[altNames[i]] = styleCache[name]; ++hits; if (i && hits === 1) { missing = styleNames.slice(0, i); missingAltNames = altNames.slice(0, i); } } else if (hits) { (missing || (missing = [])).push(name); (missingAltNames || (missingAltNames = [])).push(altNames[i]); } } if (hits < n) { missing = missing || styleNames; missingAltNames = missingAltNames || altNames; styleInfo = me.styleInfo; styles = me.el.getStyle(missing); for (i = missing.length; i--; ) { name = missing[i]; info = styleInfo[name]; value = styles[name]; if (info && info.parseInt) { value = parseInt(value, 10) || 0; } values[missingAltNames[i]] = value; styleCache[name] = value; } } return values; }, hasProp: function(propName) { return this.getProp(propName) != null; }, hasDomProp: function(propName) { return this.getDomProp(propName) != null; }, invalidate: function(options) { this.context.queueInvalidate(this, options); }, markDirty: function() { if (++this.dirtyCount === 1) { this.context.queueFlush(this); } }, onBoxMeasured: function() { var boxParent = this.boxParent, state = this.state; if (boxParent && boxParent.widthModel.shrinkWrap && !state.boxMeasured && this.measuresBox) { state.boxMeasured = 1; boxParent.boxChildMeasured(); } }, parseMargins: function(comp, margins) { if (margins === true) { margins = 5; } var type = typeof margins, ret; if (type === 'string' || type === 'number') { ret = comp.parseBox(margins); } else if (margins) { ret = { top: 0, right: 0, bottom: 0, left: 0 }; if (margins) { margins = Ext.apply(ret, comp.parseBox(margins)); } } return ret; }, peek: function(propName) { return this.props[propName]; }, recoverProp: function(propName, oldProps, oldDirty) { var me = this, props = me.props, dirty; if (propName in oldProps) { props[propName] = oldProps[propName]; if (oldDirty && propName in oldDirty) { dirty = me.dirty || (me.dirty = {}); dirty[propName] = oldDirty[propName]; } } }, redo: function(deep) { var me = this, items, len, i; me.revertProps(me.props); if (deep && me.wrapsComponent) { if (me.childItems) { for (i = 0 , items = me.childItems , len = items.length; i < len; i++) { items[i].redo(deep); } } for (i = 0 , items = me.children , len = items.length; i < len; i++) { items[i].redo(); } } }, removeEl: function(nameOrEl, owner) { var me = this, src, el; if (nameOrEl) { if (nameOrEl.dom) { el = nameOrEl; } else { src = me.target; if (owner) { src = owner; } el = src[nameOrEl]; if (typeof el === 'function') { el = el.call(src); if (el === me.el) { return this; } } } if (el) { me.context.removeEl(me, el); } } }, revertProps: function(props) { var name, flushed = this.flushedProps, reverted = {}; for (name in props) { if (flushed.hasOwnProperty(name)) { reverted[name] = props[name]; } } this.writeProps(reverted); }, setAttribute: function(name, value) { var me = this; if (!me.attributes) { me.attributes = {}; } me.attributes[name] = value; me.markDirty(); }, setBox: function(box) { var me = this; if ('left' in box) { me.setProp('x', box.left); } if ('top' in box) { me.setProp('y', box.top); } me.setSize(box.width, box.height); }, setContentHeight: function(height, measured) { if (!measured && this.hasRawContent) { return 1; } return this.setProp('contentHeight', height); }, setContentWidth: function(width, measured) { if (!measured && this.hasRawContent) { return 1; } return this.setProp('contentWidth', width); }, setContentSize: function(width, height, measured) { return this.setContentWidth(width, measured) + this.setContentHeight(height, measured) === 2; }, setProp: function(propName, value, dirty) { var me = this, valueType = typeof value, info; if (valueType === 'undefined' || (valueType === 'number' && isNaN(value))) { return 0; } if (me.props[propName] === value) { return 1; } me.props[propName] = value; ++me.context.progressCount; if (dirty === false) { me.fireTriggers('domTriggers', propName); me.clearBlocks('domBlocks', propName); } else { info = me.styleInfo[propName]; if (info) { if (!me.dirty) { me.dirty = {}; } me.dirty[propName] = value; me.markDirty(); } } me.fireTriggers('triggers', propName); me.clearBlocks('blocks', propName); return 1; }, setHeight: function(height, dirty) { var me = this, comp = me.target, ownerCtContext = me.ownerCtContext, frameBody, frameInfo, min, oldHeight, rem; if (height < 0) { height = 0; } if (!me.wrapsComponent) { if (!me.setProp('height', height, dirty)) { return NaN; } } else { min = me.collapsedVert ? 0 : (comp.minHeight || 0); height = Ext.Number.constrain(height, min, comp.maxHeight); oldHeight = me.props.height; if (!me.setProp('height', height, dirty)) { return NaN; } if (ownerCtContext && !me.isComponentChild && isNaN(oldHeight)) { rem = --ownerCtContext.remainingChildDimensions; if (!rem) { ownerCtContext.setProp('containerChildrenSizeDone', true); } } frameBody = me.frameBodyContext; if (frameBody) { frameInfo = me.getFrameInfo(); frameBody[me.el.vertical ? 'setWidth' : 'setHeight'](height - frameInfo.height, dirty); } } return height; }, setWidth: function(width, dirty) { var me = this, comp = me.target, ownerCtContext = me.ownerCtContext, frameBody, frameInfo, min, oldWidth, rem; if (width < 0) { width = 0; } if (!me.wrapsComponent) { if (!me.setProp('width', width, dirty)) { return NaN; } } else { min = me.collapsedHorz ? 0 : (comp.minWidth || 0); width = Ext.Number.constrain(width, min, comp.maxWidth); oldWidth = me.props.width; if (!me.setProp('width', width, dirty)) { return NaN; } if (ownerCtContext && !me.isComponentChild && isNaN(oldWidth)) { rem = --ownerCtContext.remainingChildDimensions; if (!rem) { ownerCtContext.setProp('containerChildrenSizeDone', true); } } frameBody = me.frameBodyContext; if (frameBody) { frameInfo = me.getFrameInfo(); frameBody.setWidth(width - frameInfo.width, dirty); } } return width; }, setSize: function(width, height, dirty) { this.setWidth(width, dirty); this.setHeight(height, dirty); }, translateProps: { x: 'left', y: 'top' }, undo: function(deep) { var me = this, items, len, i; me.revertProps(me.lastBox); if (deep && me.wrapsComponent) { if (me.childItems) { for (i = 0 , items = me.childItems , len = items.length; i < len; i++) { items[i].undo(deep); } } for (i = 0 , items = me.children , len = items.length; i < len; i++) { items[i].undo(); } } }, unsetProp: function(propName) { var dirty = this.dirty; delete this.props[propName]; if (dirty) { delete dirty[propName]; } }, writeProps: function(dirtyProps, flushing) { if (!(dirtyProps && typeof dirtyProps === 'object')) { Ext.Logger.warn('writeProps expected dirtyProps to be an object'); return; } var me = this, el = me.el, styles = {}, styleCount = 0, styleInfo = me.styleInfo, info, propName, numericValue, width = dirtyProps.width, height = dirtyProps.height, target = me.target, hasWidth, hasHeight, isAbsolute, scrollbarSize, style, targetEl; if ('displayed' in dirtyProps) { el.setDisplayed(dirtyProps.displayed); } for (propName in dirtyProps) { if (flushing) { me.fireTriggers('domTriggers', propName); me.clearBlocks('domBlocks', propName); me.flushedProps[propName] = 1; } info = styleInfo[propName]; if (info && info.dom) { if (info.suffix && (numericValue = parseInt(dirtyProps[propName], 10))) { styles[propName] = numericValue + info.suffix; } else { styles[propName] = dirtyProps[propName]; } ++styleCount; } } if ('x' in dirtyProps || 'y' in dirtyProps) { if (target.isComponent) { target.setPosition(dirtyProps.x, dirtyProps.y); } else { styleCount += me.addPositionStyles(styles, dirtyProps); } } if (me.wrapsComponent && Ext.isIE9) { if ((hasWidth = width !== undefined && me.hasOverflowY) || (hasHeight = height !== undefined && me.hasOverflowX)) { isAbsolute = me.isAbsolute; if (isAbsolute === undefined) { isAbsolute = false; targetEl = me.target.getTargetEl(); style = targetEl.getStyle('position'); me.isAbsolute = isAbsolute = (style === 'absolute'); } if (isAbsolute) { scrollbarSize = Ext.getScrollbarSize(); if (hasWidth) { width = parseInt(width, 10) + scrollbarSize.width; styles.width = width + 'px'; ++styleCount; } if (hasHeight) { height = parseInt(height, 10) + scrollbarSize.height; styles.height = height + 'px'; ++styleCount; } } } } if (styleCount) { el.setStyle(styles); } }, debugHooks: { $enabled: false, addBlock: function(name, layout, propName) { (layout.blockedBy || (layout.blockedBy = {}))[this.id + '.' + propName + (name.substring(0, 3) === 'dom' ? ':dom' : '')] = 1; return this.callParent(arguments); }, addBoxChild: function(boxChildItem) { var ret = this.callParent(arguments), boxChildren = this.boxChildren, boxParents; if (boxChildren && boxChildren.length === 1) { boxParents = this.context.boxParents || (this.context.boxParents = new Ext.util.MixedCollection()); boxParents.add(this); } return ret; }, addTrigger: function(propName, inDom) { var layout = this.context.currentLayout, triggers; this.callParent(arguments); triggers = this.context.triggersByLayoutId; (triggers[layout.id] || (triggers[layout.id] = {}))[this.id + '.' + propName + (inDom ? ':dom' : '')] = { item: this, name: propName }; }, checkAuthority: function(prop) { var me = this, model = me[prop + 'Model'], layout = me.context.currentLayout, ok, setBy; if (layout === me.target.ownerLayout) { ok = model.calculated; } else if (layout.isComponentLayout) { ok = me.isTopLevel || model.auto || model.configured; } if (!ok) { setBy = me.context.getLayoutName(layout); Ext.log(setBy + ' cannot set ' + prop); } }, clearBlocks: function(name, propName) { var collection = this[name], blockedLayouts = collection && collection[propName], key = this.id + '.' + propName + (name.substring(0, 3) === 'dom' ? ':dom' : ''), layout, layoutId; if (blockedLayouts) { for (layoutId in blockedLayouts) { layout = blockedLayouts[layoutId]; delete layout.blockedBy[key]; } } return this.callParent(arguments); }, getEl: function(el) { var child = this.callParent(arguments); if (child && child !== this && child.parent !== this) { Ext.Error.raise({ msg: 'Got element from wrong component' }); } return child; }, init: function() { var me = this, ret; ret = me.callParent(arguments); if (me.context.logOn.initItem) { Ext.log(me.id, ' consumers: content=', me.consumersContentWidth, '/', me.consumersContentHeight, ', container=', me.consumersContainerWidth, '/', me.consumersContainerHeight, ', size=', me.consumersWidth, '/', me.consumersHeight); } return ret; }, invalidate: function() { if (this.wrapsComponent) { if (this.context.logOn.invalidate) { Ext.log('invalidate: ', this.id); } } else { Ext.Error.raise({ msg: 'Cannot invalidate an element contextItem' }); } return this.callParent(arguments); }, setProp: function(propName, value, dirty) { var me = this, layout = me.context.currentLayout, setBy = me.context.getLayoutName(layout), fullName = me.id + '.' + propName, setByProps; if (value !== null) { setByProps = me.setBy || (me.setBy = {}); if (!setByProps[propName]) { setByProps[propName] = setBy; } else if (setByProps[propName] !== setBy) { Ext.log({ level: 'warn' }, 'BAD! ', fullName, ' set by ', setByProps[propName], ' and ', setBy); } } if (me.context.logOn.setProp) { if (typeof value !== 'undefined' && !isNaN(value) && me.props[propName] !== value) { Ext.log('set ', fullName, ' = ', value, ' (', dirty, ')'); } } return this.callParent(arguments); }, setHeight: function(height, dirty, force) { if (!force && this.wrapsComponent) { this.checkAuthority('height'); } return this.callParent(arguments); }, setWidth: function(width, dirty, force) { if (!force && this.wrapsComponent) { this.checkAuthority('width'); } return this.callParent(arguments); } } }, function() { var px = { dom: true, parseInt: true, suffix: 'px' }, isDom = { dom: true }, faux = { dom: false }; this.prototype.styleInfo = { containerChildrenSizeDone: faux, containerLayoutDone: faux, displayed: faux, done: faux, x: faux, y: faux, columnsChanged: faux, rowHeights: faux, viewOverflowY: faux, left: px, top: px, right: px, bottom: px, width: px, height: px, 'border-top-width': px, 'border-right-width': px, 'border-bottom-width': px, 'border-left-width': px, 'margin-top': px, 'margin-right': px, 'margin-bottom': px, 'margin-left': px, 'padding-top': px, 'padding-right': px, 'padding-bottom': px, 'padding-left': px, 'line-height': isDom, display: isDom, clear: isDom }; }); Ext.define('Ext.layout.Context', { requires: [ 'Ext.perf.Monitor', 'Ext.util.Queue', 'Ext.layout.ContextItem', 'Ext.layout.Layout', 'Ext.fx.Anim', 'Ext.fx.Manager' ], remainingLayouts: 0, state: 0, cycleWatchDog: 200, constructor: function(config) { var me = this; Ext.apply(me, config); me.items = {}; me.layouts = {}; me.blockCount = 0; me.cycleCount = 0; me.flushCount = 0; me.calcCount = 0; me.animateQueue = me.newQueue(); me.completionQueue = me.newQueue(); me.finalizeQueue = me.newQueue(); me.finishQueue = me.newQueue(); me.flushQueue = me.newQueue(); me.invalidateData = {}; me.layoutQueue = me.newQueue(); me.invalidQueue = []; me.triggers = { data: {}, dom: {} }; }, callLayout: function(layout, methodName) { this.currentLayout = layout; layout[methodName](this.getCmp(layout.owner)); }, cancelComponent: function(comp, isChild, isDestroying) { var me = this, components = comp, isArray = !comp.isComponent, length = isArray ? components.length : 1, i, k, klen, items, layout, newQueue, oldQueue, entry, temp, ownerCtContext; for (i = 0; i < length; ++i) { if (isArray) { comp = components[i]; } if (isDestroying && comp.ownerCt) { ownerCtContext = this.items[comp.ownerCt.el.id]; if (ownerCtContext) { Ext.Array.remove(ownerCtContext.childItems, me.getCmp(comp)); } } if (!isChild) { oldQueue = me.invalidQueue; klen = oldQueue.length; if (klen) { me.invalidQueue = newQueue = []; for (k = 0; k < klen; ++k) { entry = oldQueue[k]; temp = entry.item.target; if (temp !== comp && !temp.up(comp)) { newQueue.push(entry); } } } } layout = comp.componentLayout; me.cancelLayout(layout); if (layout.getLayoutItems) { items = layout.getLayoutItems(); if (items.length) { me.cancelComponent(items, true); } } if (comp.isContainer && !comp.collapsed) { layout = comp.layout; me.cancelLayout(layout); items = layout.getVisibleItems(); if (items.length) { me.cancelComponent(items, true); } } } }, cancelLayout: function(layout) { var me = this; me.completionQueue.remove(layout); me.finalizeQueue.remove(layout); me.finishQueue.remove(layout); me.layoutQueue.remove(layout); if (layout.running) { me.layoutDone(layout); } layout.ownerContext = null; }, clearTriggers: function(layout, inDom) { var id = layout.id, collection = this.triggers[inDom ? 'dom' : 'data'], triggers = collection && collection[id], length = (triggers && triggers.length) || 0, i, item, trigger; for (i = 0; i < length; ++i) { trigger = triggers[i]; item = trigger.item; collection = inDom ? item.domTriggers : item.triggers; delete collection[trigger.prop][id]; } }, flush: function() { var me = this, items = me.flushQueue.clear(), length = items.length, i; if (length) { ++me.flushCount; for (i = 0; i < length; ++i) { items[i].flush(); } } }, flushAnimations: function() { var me = this, items = me.animateQueue.clear(), len = items.length, i; if (len) { for (i = 0; i < len; i++) { if (items[i].target.animate !== false) { items[i].flushAnimations(); } } Ext.fx.Manager.runner(); } }, flushInvalidates: function() { var me = this, queue = me.invalidQueue, length = queue && queue.length, comp, components, entry, i; me.invalidQueue = []; if (length) { components = []; for (i = 0; i < length; ++i) { comp = (entry = queue[i]).item.target; if (!comp.container.isDetachedBody) { components.push(comp); if (entry.options) { me.invalidateData[comp.id] = entry.options; } } } me.invalidate(components, null); } }, flushLayouts: function(queueName, methodName, dontClear) { var me = this, layouts = dontClear ? me[queueName].items : me[queueName].clear(), length = layouts.length, i, layout; if (length) { for (i = 0; i < length; ++i) { layout = layouts[i]; if (!layout.running) { me.callLayout(layout, methodName); } } me.currentLayout = null; } }, getCmp: function(cmp) { return this.getItem(cmp, cmp.el); }, getEl: function(parent, el) { var item = this.getItem(el, el); if (!item.parent) { item.parent = parent; if (parent.children.length) { parent.children.push(item); } else { parent.children = [ item ]; } } return item; }, getItem: function(target, el) { var id = el.id, items = this.items, item = items[id] || (items[id] = new Ext.layout.ContextItem({ context: this, target: target, el: el })); return item; }, handleFailure: function() { var layouts = this.layouts, layout, key; Ext.failedLayouts = (Ext.failedLayouts || 0) + 1; for (key in layouts) { layout = layouts[key]; if (layouts.hasOwnProperty(key)) { layout.running = false; layout.ownerContext = null; } } if (Ext.repoDevMode && !this.pageAnalyzerMode) { Ext.Error.raise('Layout run failed'); } else { Ext.log.error('Layout run failed'); } }, invalidate: function(components, full) { var me = this, isArray = !components.isComponent, containerLayoutDone, ownerLayout, firstTime, i, comp, item, items, length, componentLayout, layout, invalidateOptions, token, skipLayout; for (i = 0 , length = isArray ? components.length : 1; i < length; ++i) { comp = isArray ? components[i] : components; if (comp.rendered && !comp.hidden) { ownerLayout = comp.ownerLayout; componentLayout = comp.componentLayout; firstTime = !componentLayout.ownerContext; skipLayout = false; if ((!ownerLayout || !ownerLayout.needsItemSize) && comp.liquidLayout) { skipLayout = true; } if (!skipLayout || (ownerLayout && ownerLayout.setsItemSize)) { item = me.getCmp(comp); layout = (comp.isContainer && !comp.collapsed) ? comp.layout : null; invalidateOptions = me.invalidateData[item.id]; delete me.invalidateData[item.id]; token = item.init(full, invalidateOptions); } if (skipLayout) { continue; } if (invalidateOptions) { me.processInvalidate(invalidateOptions, item, 'before'); } if (componentLayout.beforeLayoutCycle) { componentLayout.beforeLayoutCycle(item); } if (layout && layout.beforeLayoutCycle) { layout.beforeLayoutCycle(item); } token = item.initContinue(token); containerLayoutDone = true; if (componentLayout.getLayoutItems) { componentLayout.renderChildren(); items = componentLayout.getLayoutItems(); if (items.length) { me.invalidate(items, true); } } if (layout) { containerLayoutDone = false; layout.renderChildren(); if (layout.needsItemSize || layout.activeItemCount) { items = layout.getVisibleItems(); if (items.length) { me.invalidate(items, true); } } } item.initDone(containerLayoutDone); me.resetLayout(componentLayout, item, firstTime); if (layout) { me.resetLayout(layout, item, firstTime); } item.initAnimation(); if (invalidateOptions) { me.processInvalidate(invalidateOptions, item, 'after'); } } } me.currentLayout = null; }, isDescendant: function(ancestor, descendant) { if (ancestor.isContainer) { for (var c = descendant.ownerCt; c; c = c.ownerCt) { if (c === ancestor) { return true; } } } return false; }, layoutDone: function(layout) { var ownerContext = layout.ownerContext; layout.running = false; if (layout.isComponentLayout) { if (ownerContext.measuresBox) { ownerContext.onBoxMeasured(); } ownerContext.setProp('done', true); } else { ownerContext.setProp('containerLayoutDone', true); } --this.remainingLayouts; ++this.progressCount; }, newQueue: function() { return new Ext.util.Queue(); }, processInvalidate: function(options, item, name) { if (options[name]) { var me = this, currentLayout = me.currentLayout; me.currentLayout = options.layout || null; options[name](item, options); me.currentLayout = currentLayout; } }, queueAnimation: function(item) { this.animateQueue.add(item); }, queueCompletion: function(layout) { this.completionQueue.add(layout); }, queueFinalize: function(layout) { this.finalizeQueue.add(layout); }, queueFlush: function(item) { this.flushQueue.add(item); }, chainFns: function(oldOptions, newOptions, funcName) { var me = this, oldLayout = oldOptions.layout, newLayout = newOptions.layout, oldFn = oldOptions[funcName], newFn = newOptions[funcName]; return function(contextItem) { var prev = me.currentLayout; if (oldFn) { me.currentLayout = oldLayout; oldFn.call(oldOptions.scope || oldOptions, contextItem, oldOptions); } me.currentLayout = newLayout; newFn.call(newOptions.scope || newOptions, contextItem, newOptions); me.currentLayout = prev; }; }, purgeInvalidates: function() { var me = this, newQueue = [], oldQueue = me.invalidQueue, oldLength = oldQueue.length, oldIndex, newIndex, newEntry, newComp, oldEntry, oldComp, keep; for (oldIndex = 0; oldIndex < oldLength; ++oldIndex) { oldEntry = oldQueue[oldIndex]; oldComp = oldEntry.item.target; keep = true; for (newIndex = newQueue.length; newIndex--; ) { newEntry = newQueue[newIndex]; newComp = newEntry.item.target; if (oldComp.isLayoutChild(newComp)) { keep = false; break; } if (newComp.isLayoutChild(oldComp)) { Ext.Array.erase(newQueue, newIndex, 1); } } if (keep) { newQueue.push(oldEntry); } } me.invalidQueue = newQueue; }, queueInvalidate: function(item, options) { var me = this, newQueue = [], oldQueue = me.invalidQueue, index = oldQueue.length, comp, old, oldComp, oldOptions, oldState; if (item.isComponent) { item = me.getCmp(comp = item); } else { comp = item.target; } item.invalid = true; while (index--) { old = oldQueue[index]; oldComp = old.item.target; if (!comp.isFloating && comp.up(oldComp)) { return; } if (oldComp === comp) { if (!(oldOptions = old.options)) { old.options = options; } else if (options) { if (options.widthModel) { oldOptions.widthModel = options.widthModel; } if (options.heightModel) { oldOptions.heightModel = options.heightModel; } if (!(oldState = oldOptions.state)) { oldOptions.state = options.state; } else if (options.state) { Ext.apply(oldState, options.state); } if (options.before) { oldOptions.before = me.chainFns(oldOptions, options, 'before'); } if (options.after) { oldOptions.after = me.chainFns(oldOptions, options, 'after'); } } return; } if (!oldComp.isLayoutChild(comp)) { newQueue.push(old); } } newQueue.push({ item: item, options: options }); me.invalidQueue = newQueue; }, queueItemLayouts: function(item) { var comp = item.isComponent ? item : item.target, layout = comp.componentLayout; if (!layout.pending && !layout.invalid && !layout.done) { this.queueLayout(layout); } layout = comp.layout; if (layout && !layout.pending && !layout.invalid && !layout.done && !comp.collapsed) { this.queueLayout(layout); } }, queueLayout: function(layout) { this.layoutQueue.add(layout); layout.pending = true; }, removeEl: function(parent, el) { var id = el.id, children = parent.children, items = this.items; if (children) { Ext.Array.remove(children, items[id]); } delete items[id]; }, resetLayout: function(layout, ownerContext, firstTime) { var me = this; me.currentLayout = layout; layout.done = false; layout.pending = true; layout.firedTriggers = 0; me.layoutQueue.add(layout); if (firstTime) { me.layouts[layout.id] = layout; layout.running = true; if (layout.finishedLayout) { me.finishQueue.add(layout); } ++me.remainingLayouts; ++layout.layoutCount; layout.ownerContext = ownerContext; layout.beginCount = 0; layout.blockCount = 0; layout.calcCount = 0; layout.triggerCount = 0; if (!layout.initialized) { layout.initLayout(); } layout.beginLayout(ownerContext); } else { ++layout.beginCount; if (!layout.running) { ++me.remainingLayouts; layout.running = true; if (layout.isComponentLayout) { ownerContext.unsetProp('done'); } me.completionQueue.remove(layout); me.finalizeQueue.remove(layout); } } layout.beginLayoutCycle(ownerContext, firstTime); }, run: function() { var me = this, flushed = false, watchDog = me.cycleWatchDog; me.purgeInvalidates(); me.flushInvalidates(); me.state = 1; me.totalCount = me.layoutQueue.getCount(); me.flush(); while ((me.remainingLayouts || me.invalidQueue.length) && watchDog--) { if (me.invalidQueue.length) { me.flushInvalidates(); } if (me.runCycle()) { flushed = false; } else if (!flushed) { me.flush(); flushed = true; me.flushLayouts('completionQueue', 'completeLayout'); } else if (!me.invalidQueue.length) { me.state = 2; break; } if (!(me.remainingLayouts || me.invalidQueue.length)) { me.flush(); me.flushLayouts('completionQueue', 'completeLayout'); me.flushLayouts('finalizeQueue', 'finalizeLayout'); } } return me.runComplete(); }, runComplete: function() { var me = this; me.state = 2; if (me.remainingLayouts) { me.handleFailure(); return false; } me.flush(); me.flushLayouts('finishQueue', 'finishedLayout', true); me.flushLayouts('finishQueue', 'notifyOwner'); me.flush(); me.flushAnimations(); return true; }, runCycle: function() { var me = this, layouts = me.layoutQueue.clear(), length = layouts.length, i; ++me.cycleCount; me.progressCount = 0; for (i = 0; i < length; ++i) { me.runLayout(me.currentLayout = layouts[i]); } me.currentLayout = null; return me.progressCount > 0; }, runLayout: function(layout) { var me = this, ownerContext = me.getCmp(layout.owner); layout.pending = false; if (ownerContext.state.blocks) { return; } layout.done = true; ++layout.calcCount; ++me.calcCount; layout.calculate(ownerContext); if (layout.done) { me.layoutDone(layout); if (layout.completeLayout) { me.queueCompletion(layout); } if (layout.finalizeLayout) { me.queueFinalize(layout); } } else if (!layout.pending && !layout.invalid && !(layout.blockCount + layout.triggerCount - layout.firedTriggers)) { me.queueLayout(layout); } }, setItemSize: function(item, width, height) { var items = item, len = 1, contextItem, i; if (item.isComposite) { items = item.elements; len = items.length; item = items[0]; } else if (!item.dom && !item.el) { len = items.length; item = items[0]; } for (i = 0; i < len; ) { contextItem = this.get(item); contextItem.setSize(width, height); item = items[++i]; } }, debugHooks: { $enabled: false, pageAnalyzerMode: true, logOn: { 0: 0 }, cancelComponent: function(comp) { if (this.logOn.cancelComponent) { Ext.log('cancelCmp: ', comp.id); } this.callParent(arguments); }, cancelLayout: function(layout) { if (this.logOn.cancelLayout) { Ext.log('cancelLayout: ', this.getLayoutName(layout)); } this.callParent(arguments); }, callLayout: function(layout, methodName) { var accum = this.accumByType[layout.type], frame = accum && accum.enter(); this.callParent(arguments); if (accum) { frame.leave(); } }, checkRemainingLayouts: function() { var me = this, expected = 0, key, layout; for (key in me.layouts) { layout = me.layouts[key]; if (me.layouts.hasOwnProperty(key) && layout.running) { ++expected; } } if (me.remainingLayouts !== expected) { Ext.Error.raise({ msg: 'Bookkeeping error me.remainingLayouts' }); } }, flush: function() { if (this.logOn.flush) { var items = this.flushQueue; Ext.log('--- Flush ', items && items.getCount()); } return this.callParent(arguments); }, flushInvalidates: function() { if (this.logOn.flushInvalidate) { Ext.log('>> flushInvalidates'); } var ret = this.callParent(arguments); if (this.logOn.flushInvalidate) { Ext.log('<< flushInvalidates'); } return ret; }, getCmp: function(target) { var ret = this.callParent(arguments); if (!ret.wrapsComponent) { Ext.Error.raise({ msg: target.id + ' is not a component' }); } return ret; }, getEl: function(parent, target) { var ret = this.callParent(arguments); if (ret && ret.wrapsComponent) { Ext.Error.raise({ msg: parent.id + '/' + target.id + ' is a component (expected element)' }); } return ret; }, getLayoutName: function(layout) { return layout.owner.id + '<' + layout.type + '>'; }, layoutDone: function(layout) { var me = this, name = me.getLayoutName(layout); if (me.logOn.layoutDone) { Ext.log('layoutDone: ', name, ' ( ', me.remainingLayouts, ' running)'); } if (!layout.running) { Ext.Error.raise({ msg: name + ' is already done' }); } if (!me.remainingLayouts) { Ext.Error.raise({ msg: name + ' finished but no layouts are running' }); } me.callParent(arguments); }, layoutTreeHasFailures: function(layout, reported) { var me = this; function hasFailure(lo) { var failure = !lo.done, key, childLayout; if (lo.done) { for (key in me.layouts) { if (me.layouts.hasOwnProperty(key)) { childLayout = me.layouts[key]; if (childLayout.owner.ownerLayout === lo) { if (hasFailure(childLayout)) { failure = true; } } } } } return failure; } if (hasFailure(layout)) { return true; } function markReported(lo) { var key, childLayout; reported[lo.id] = 1; for (key in me.layouts) { if (me.layouts.hasOwnProperty(key)) { childLayout = me.layouts[key]; if (childLayout.owner.ownerLayout === lo) { markReported(childLayout); } } } } markReported(layout); return false; }, queueLayout: function(layout) { if (layout.done || layout.blockCount || layout.pending) { Ext.Error.raise({ msg: this.getLayoutName(layout) + ' should not be queued for layout' }); } if (this.logOn.queueLayout) { Ext.log('Queue ', this.getLayoutName(layout)); } return this.callParent(arguments); }, reportLayoutResult: function(layout, reported) { var me = this, owner = layout.owner, ownerContext = me.getCmp(owner), blockedBy = [], triggeredBy = [], key, value, i, length, childLayout, item, setBy, info; reported[layout.id] = 1; for (key in layout.blockedBy) { if (layout.blockedBy.hasOwnProperty(key)) { blockedBy.push(layout.blockedBy[key]); } } blockedBy.sort(); for (key in me.triggersByLayoutId[layout.id]) { if (me.triggersByLayoutId[layout.id].hasOwnProperty(key)) { value = me.triggersByLayoutId[layout.id][key]; triggeredBy.push({ name: key, info: value }); } } triggeredBy.sort(function(a, b) { return a.name < b.name ? -1 : (b.name < a.name ? 1 : 0); }); Ext.log({ indent: 1 }, (layout.done ? '++' : '--'), me.getLayoutName(layout), (ownerContext.isBoxParent ? ' [isBoxParent]' : ''), (ownerContext.boxChildren ? ' - boxChildren: ' + ownerContext.state.boxesMeasured + '/' + ownerContext.boxChildren.length : ''), ownerContext.boxParent ? (' - boxParent: ' + ownerContext.boxParent.id) : '', ' - size: ', ownerContext.widthModel.name, '/', ownerContext.heightModel.name); if (!layout.done || me.reportOnSuccess) { if (blockedBy.length) { ++Ext.log.indent; Ext.log({ indent: 1 }, 'blockedBy: count=', layout.blockCount); length = blockedBy.length; for (i = 0; i < length; i++) { Ext.log(blockedBy[i]); } Ext.log.indent -= 2; } if (triggeredBy.length) { ++Ext.log.indent; Ext.log({ indent: 1 }, 'triggeredBy: count=' + layout.triggerCount); length = triggeredBy.length; for (i = 0; i < length; i++) { info = value.info || value; item = info.item; setBy = (item.setBy && item.setBy[info.name]) || '?'; value = triggeredBy[i]; Ext.log(value.name, ' (', item.props[info.name], ') dirty: ', (item.dirty ? !!item.dirty[info.name] : false), ', setBy: ', setBy); } Ext.log.indent -= 2; } } for (key in me.layouts) { if (me.layouts.hasOwnProperty(key)) { childLayout = me.layouts[key]; if (!childLayout.done && childLayout.owner.ownerLayout === layout) { me.reportLayoutResult(childLayout, reported); } } } for (key in me.layouts) { if (me.layouts.hasOwnProperty(key)) { childLayout = me.layouts[key]; if (childLayout.done && childLayout.owner.ownerLayout === layout) { me.reportLayoutResult(childLayout, reported); } } } --Ext.log.indent; }, resetLayout: function(layout) { var me = this, type = layout.type, name = me.getLayoutName(layout), accum = me.accumByType[type], frame; if (me.logOn.resetLayout) { Ext.log('resetLayout: ', name, ' ( ', me.remainingLayouts, ' running)'); } if (!me.state) { if (!accum && me.profileLayoutsByType) { me.accumByType[type] = accum = Ext.Perf.get('layout_' + layout.type); } me.numByType[type] = (me.numByType[type] || 0) + 1; } frame = accum && accum.enter(); me.callParent(arguments); if (accum) { frame.leave(); } me.checkRemainingLayouts(); }, round: function(t) { return Math.round(t * 1000) / 1000; }, run: function() { var me = this, ret, time, key, i, layout, boxParent, children, n, reported, unreported, calcs, total, calcsLength, calc; me.accumByType = {}; me.calcsByType = {}; me.numByType = {}; me.timesByType = {}; me.triggersByLayoutId = {}; Ext.log.indentSize = 3; Ext.log('==================== LAYOUT ===================='); time = Ext.perf.getTimestamp(); ret = me.callParent(arguments); time = Ext.perf.getTimestamp() - time; if (me.logOn.boxParent && me.boxParents) { for (key in me.boxParents) { if (me.boxParents.hasOwnProperty(key)) { boxParent = me.boxParents[key]; children = boxParent.boxChildren; n = children.length; Ext.log('boxParent: ', boxParent.id); for (i = 0; i < n; ++i) { Ext.log(' --> ', children[i].id); } } } } if (ret) { Ext.log('----------------- SUCCESS -----------------'); } else { Ext.log({ level: 'error' }, '----------------- FAILURE -----------------'); } for (key in me.layouts) { if (me.layouts.hasOwnProperty(key)) { layout = me.layouts[key]; if (layout.running) { Ext.log.error('Layout left running: ', me.getLayoutName(layout)); } if (layout.ownerContext) { Ext.log.error('Layout left connected: ', me.getLayoutName(layout)); } } } if (!ret || me.reportOnSuccess) { reported = {}; unreported = 0; for (key in me.layouts) { if (me.layouts.hasOwnProperty(key)) { layout = me.layouts[key]; if (me.items[layout.owner.el.id].isTopLevel) { if (me.reportOnSuccess || me.layoutTreeHasFailures(layout, reported)) { me.reportLayoutResult(layout, reported); } } } } for (key in me.layouts) { if (me.layouts.hasOwnProperty(key)) { layout = me.layouts[key]; if (!reported[layout.id]) { if (!unreported) { Ext.log('----- Unreported!! -----'); } ++unreported; me.reportLayoutResult(layout, reported); } } } } Ext.log('Cycles: ', me.cycleCount, ', Flushes: ', me.flushCount, ', Calculates: ', me.calcCount, ' in ', me.round(time), ' msec'); Ext.log('Calculates by type:'); calcs = []; for (key in me.numByType) { if (me.numByType.hasOwnProperty(key)) { total = me.numByType[key]; calcs.push({ type: key, total: total, calcs: me.calcsByType[key], multiple: Math.round(me.calcsByType[key] / total * 10) / 10, calcTime: me.round(me.timesByType[key]), avgCalcTime: me.round(me.timesByType[key] / me.calcsByType[key]) }); } } calcs.sort(function(a, b) { return b.calcTime - a.calcTime; }); calcsLength = calcs.length; for (i = 0; i < calcsLength; i++) { calc = calcs[i]; Ext.log(calc.type, ': ', calc.total, ' in ', calc.calcs, ' tries (', calc.multiple, 'x) at ', calc.calcTime, ' msec (avg ', calc.avgCalcTime, ' msec)'); } return ret; }, runCycle: function() { if (this.logOn.runCycle) { Ext.log('>>> Cycle ', this.cycleCount, ' (queue length: ', this.layoutQueue.length, ')'); } return this.callParent(arguments); }, runLayout: function(layout) { var me = this, type = layout.type, accum = me.accumByType[type], frame, ret, time; if (me.logOn.calculate) { Ext.log('-- calculate ', this.getLayoutName(layout)); } frame = accum && accum.enter(); time = Ext.perf.getTimestamp(); ret = me.callParent(arguments); time = Ext.perf.getTimestamp() - time; if (accum) { frame.leave(); } me.calcsByType[type] = (me.calcsByType[type] || 0) + 1; me.timesByType[type] = (me.timesByType[type] || 0) + time; return ret; } } }); Ext.define('Ext.layout.component.FieldSet', { extend: 'Ext.layout.component.Body', alias: [ 'layout.fieldset' ], type: 'fieldset', defaultCollapsedWidth: 100, beforeLayoutCycle: function(ownerContext) { if (ownerContext.target.collapsed) { ownerContext.heightModel = this.sizeModels.shrinkWrap; } }, beginLayout: function(ownerContext) { var legend = this.owner.legend; this.callParent([ ownerContext ]); if (legend) { ownerContext.legendContext = ownerContext.context.getCmp(legend); } }, beginLayoutCycle: function(ownerContext) { var target = ownerContext.target, lastSize; this.callParent(arguments); if (target.collapsed) { ownerContext.setContentHeight(0); ownerContext.restoreMinHeight = target.minHeight; delete target.minHeight; if (ownerContext.widthModel.shrinkWrap) { lastSize = this.lastComponentSize; ownerContext.setContentWidth((lastSize && lastSize.contentWidth) || this.defaultCollapsedWidth); } } }, finishedLayout: function(ownerContext) { var owner = this.owner, restore = ownerContext.restoreMinHeight; this.callParent(arguments); if (restore) { owner.minHeight = restore; } }, calculateOwnerWidthFromContentWidth: function(ownerContext, contentWidth) { var legendContext = ownerContext.legendContext; if (legendContext) { contentWidth = Math.max(contentWidth, legendContext.getProp('width')); } return this.callParent([ ownerContext, contentWidth ]); }, calculateOwnerHeightFromContentHeight: function(ownerContext, contentHeight) { var border = ownerContext.getBorderInfo(), legendContext = ownerContext.legendContext; return ownerContext.getProp('contentHeight') + ownerContext.getPaddingInfo().height + (Ext.isIE8 ? ownerContext.bodyContext.getPaddingInfo().top : 0) + (legendContext ? legendContext.getProp('height') : border.top) + border.bottom; }, publishInnerHeight: function(ownerContext, height) { var legendContext = ownerContext.legendContext, legendHeight = 0; if (legendContext) { legendHeight = legendContext.getProp('height'); } if (legendHeight === undefined) { this.done = false; } else { this.callParent([ ownerContext, height - legendHeight ]); } }, getLayoutItems: function() { var legend = this.owner.legend; return legend ? [ legend ] : []; } }); Ext.define('Ext.layout.container.Absolute', { alias: 'layout.absolute', extend: 'Ext.layout.container.Anchor', alternateClassName: 'Ext.layout.AbsoluteLayout', targetCls: Ext.baseCSSPrefix + 'abs-layout-ct', itemCls: Ext.baseCSSPrefix + 'abs-layout-item', ignoreOnContentChange: true, type: 'absolute', adjustWidthAnchor: function(value, childContext) { var padding = this.targetPadding, x = childContext.getStyle('left'); return value - x + padding.left; }, adjustHeightAnchor: function(value, childContext) { var padding = this.targetPadding, y = childContext.getStyle('top'); return value - y + padding.top; }, isItemLayoutRoot: function(item) { return this.ignoreOnContentChange || this.callParent(arguments); }, isItemShrinkWrap: function(item) { return true; }, beginLayout: function(ownerContext) { var me = this, target = me.getTarget(); me.callParent(arguments); if (target.dom !== document.body) { target.position(); } me.targetPadding = ownerContext.targetContext.getPaddingInfo(); }, isItemBoxParent: function(itemContext) { return true; }, onContentChange: function() { if (this.ignoreOnContentChange) { return false; } return this.callParent(arguments); }, calculateContentSize: function(ownerContext, dimensions) { var me = this, containerDimensions = (dimensions || 0) | ((ownerContext.widthModel.shrinkWrap ? 1 : 0) | (ownerContext.heightModel.shrinkWrap ? 2 : 0)), calcWidth = (containerDimensions & 1) || undefined, calcHeight = (containerDimensions & 2) || undefined, childItems = ownerContext.childItems, length = childItems.length, contentHeight = 0, contentWidth = 0, needed = 0, props = ownerContext.props, targetPadding, child, childContext, height, i, margins, width; if (calcWidth) { if (isNaN(props.contentWidth)) { ++needed; } else { calcWidth = undefined; } } if (calcHeight) { if (isNaN(props.contentHeight)) { ++needed; } else { calcHeight = undefined; } } if (needed) { for (i = 0; i < length; ++i) { childContext = childItems[i]; child = childContext.target; height = calcHeight && childContext.getProp('height'); width = calcWidth && childContext.getProp('width'); margins = childContext.getMarginInfo(); height += margins.bottom; width += margins.right; contentHeight = Math.max(contentHeight, (child.y || 0) + height); contentWidth = Math.max(contentWidth, (child.x || 0) + width); if (isNaN(contentHeight) && isNaN(contentWidth)) { me.done = false; return; } } if (calcWidth || calcHeight) { targetPadding = ownerContext.targetContext.getPaddingInfo(); } if (calcWidth && !ownerContext.setContentWidth(contentWidth + targetPadding.width)) { me.done = false; } if (calcHeight && !ownerContext.setContentHeight(contentHeight + targetPadding.height)) { me.done = false; } } } }); Ext.define('Ext.layout.container.Accordion', { extend: 'Ext.layout.container.VBox', alias: 'layout.accordion', type: 'accordion', alternateClassName: 'Ext.layout.AccordionLayout', targetCls: Ext.baseCSSPrefix + 'accordion-layout-ct', itemCls: [ Ext.baseCSSPrefix + 'box-item', Ext.baseCSSPrefix + 'accordion-item' ], align: 'stretch', enableSplitters: false, fill: true, titleCollapse: true, hideCollapseTool: false, collapseFirst: undefined, animate: true, activeOnTop: false, multi: false, panelCollapseMode: 'header', defaultAnimatePolicy: { y: true, height: true }, constructor: function() { var me = this; me.callParent(arguments); if (me.animate) { me.animatePolicy = {}; me.animatePolicy[me.names.x] = true; me.animatePolicy[me.names.width] = true; } else { me.animatePolicy = null; } }, beforeRenderItems: function(items) { var me = this, ln = items.length, owner = me.owner, collapseFirst = me.collapseFirst, hasCollapseFirst = Ext.isDefined(collapseFirst), expandedItem = me.getExpanded(true)[0], multi = me.multi, comp, i; for (i = 0; i < ln; i++) { comp = items[i]; if (!comp.rendered) { if (!multi || comp.collapsible !== false) { comp.collapsible = true; } if (comp.collapsible) { if (hasCollapseFirst) { comp.collapseFirst = collapseFirst; } if (me.hideCollapseTool) { comp.hideCollapseTool = me.hideCollapseTool; comp.titleCollapse = true; } else if (me.titleCollapse && comp.titleCollapse === undefined) { comp.titleCollapse = me.titleCollapse; } } comp.hideHeader = comp.width = null; comp.title = comp.title || ' '; comp.addBodyCls(Ext.baseCSSPrefix + 'accordion-body'); if (!multi) { if (expandedItem) { comp.collapsed = expandedItem !== comp; } else if (comp.hasOwnProperty('collapsed') && comp.collapsed === false) { expandedItem = comp; } else { comp.collapsed = true; } owner.mon(comp, 'show', me.onComponentShow, me); } comp.headerOverCls = Ext.baseCSSPrefix + 'accordion-hd-over'; } } if (!me.processing && !multi) { if (!expandedItem) { if (ln) { items[0].collapsed = false; } } else if (me.activeOnTop) { expandedItem.collapsed = false; me.configureItem(expandedItem); if (owner.items.indexOf(expandedItem) > 0) { owner.insert(0, expandedItem); } } } }, getItemsRenderTree: function(items) { this.beforeRenderItems(items); return this.callParent(arguments); }, renderItems: function(items, target) { this.beforeRenderItems(items); this.callParent(arguments); }, configureItem: function(item) { this.callParent(arguments); item.ignoreHeaderBorderManagement = true; item.animCollapse = false; if (this.fill) { item.flex = 1; } }, beginLayout: function(ownerContext) { this.callParent(arguments); this.updatePanelClasses(ownerContext); }, updatePanelClasses: function(ownerContext) { var children = ownerContext.visibleItems, ln = children.length, siblingCollapsed = true, i, child, header; for (i = 0; i < ln; i++) { child = children[i]; header = child.header; header.addCls(Ext.baseCSSPrefix + 'accordion-hd'); if (siblingCollapsed) { header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded'); } else { header.addCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded'); } if (i + 1 === ln && child.collapsed) { header.addCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed'); } else { header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed'); } siblingCollapsed = child.collapsed; } }, onBeforeComponentExpand: function(toExpand) { var me = this, owner = me.owner, multi = me.multi, moveToTop = !multi && !me.animate && me.activeOnTop, expanded, previousValue, anim; if (!me.processing) { me.processing = true; previousValue = owner.deferLayouts; owner.deferLayouts = true; if (!multi) { expanded = me.getExpanded()[0]; if (expanded && expanded !== toExpand) { anim = expanded.$layoutAnim; if (anim) { anim.jumpToEnd(); } expanded.collapse(); } } if (moveToTop) { Ext.suspendLayouts(); owner.insert(0, toExpand); Ext.resumeLayouts(); } owner.deferLayouts = previousValue; me.processing = false; } }, onBeforeComponentCollapse: function(comp) { var me = this, owner = me.owner, toExpand, expanded, previousValue; if (me.owner.items.getCount() === 1) { return false; } if (!me.processing) { me.processing = true; previousValue = owner.deferLayouts; owner.deferLayouts = true; toExpand = comp.next() || comp.prev(); if (me.multi) { expanded = me.getExpanded(); if (expanded.length === 1) { toExpand.expand(); } } else if (toExpand) { toExpand.expand(); } owner.deferLayouts = previousValue; me.processing = false; } }, onComponentShow: function(comp) { this.onBeforeComponentExpand(comp); }, onAdd: function(item) { var me = this; me.callParent(arguments); if (item.collapseMode === 'placeholder') { item.collapseMode = me.panelCollapseMode; } item.collapseDirection = item.headerPosition; if (me.layoutCount && !me.multi && me.owner.items.getCount() > 1) { me.processing = true; item.collapse(); me.processing = false; } }, onRemove: function(panel, destroying) { var me = this, item; me.callParent(arguments); if (!me.owner.destroying && !me.multi && !panel.collapsed) { item = me.owner.items.first(); if (item) { item.expand(); } } }, getExpanded: function(explicitCheck) { var items = this.owner.items.items, len = items.length, i = 0, out = [], add, item; for (; i < len; ++i) { item = items[i]; if (!item.hidden) { if (explicitCheck) { add = item.hasOwnProperty('collapsed') && item.collapsed === false; } else { add = !item.collapsed; } if (add) { out.push(item); } } } return out; }, afterCollapse: Ext.emptyFn, afterExpand: Ext.emptyFn }); Ext.define('Ext.layout.container.Center', { extend: 'Ext.layout.container.Fit', alias: [ 'layout.center', 'layout.ux.center' ], alternateClassName: 'Ext.ux.layout.Center', type: 'center', percentRe: /^\d+(?:\.\d+)?\%$/, itemCls: Ext.baseCSSPrefix + 'center-layout-item', childEls: [ 'targetEl' ], renderTpl: [ '' ], targetElCls: Ext.baseCSSPrefix + 'center-target', beginLayout: function(ownerContext) { var me = this, percentRe = me.percentRe, childItems, len, i, itemContext, item, widthModel, heightModel; me.callParent([ ownerContext ]); childItems = ownerContext.childItems; for (i = 0 , len = childItems.length; i < len; ++i) { itemContext = childItems[i]; item = itemContext.target; widthModel = itemContext.widthModel; heightModel = itemContext.heightModel; if (percentRe.test(item.width)) { item.getEl().setStyle('width', ''); } if (percentRe.test(item.height)) { item.getEl().setStyle('height', ''); } } ownerContext.targetElContext = ownerContext.getEl('targetEl', me); }, beginLayoutCycle: function(ownerContext, firstCycle) { var targetEl = this.targetEl; this.callParent([ ownerContext, firstCycle ]); targetEl.setStyle('width', ''); targetEl.setStyle('height', ''); }, getRenderData: function() { var data = this.callParent(); data.targetElCls = this.targetElCls; return data; }, getRenderTarget: function() { return this.targetEl; }, getItemSizePolicy: function(item, ownerSizeModel) { var me = this, sizeModel = ownerSizeModel || me.owner.getSizeModel(), percentRe = me.percentRe, mode = ((sizeModel.width.shrinkWrap || !percentRe.test(item.width)) ? 0 : 1) | ((sizeModel.height.shrinkWrap || !percentRe.test(item.height)) ? 0 : 2); return me.sizePolicies[mode]; }, isItemBoxParent: function(itemContext) { return true; }, isItemShrinkWrap: function(item) { return true; }, calculate: function(ownerContext) { var targetElContext = ownerContext.targetElContext, info; this.callParent([ ownerContext ]); info = ownerContext.state.info; if (ownerContext.widthModel.shrinkWrap) { targetElContext.setWidth(info.contentWidth); } if (ownerContext.heightModel.shrinkWrap) { targetElContext.setHeight(info.contentHeight); } }, getPos: function(itemContext, info, dimension) { var modelName = dimension + 'Model', size = itemContext.props[dimension], pos = 0; if (!itemContext[modelName].calculated) { size += info.margins[dimension]; } if (!info.ownerContext[modelName].shrinkWrap) { pos = Math.round((info.targetSize[dimension] - size) / 2); if (isNaN(pos)) { this.done = false; } } return Math.max(pos, 0); }, positionItemX: function(itemContext, info) { var left = this.getPos(itemContext, info, 'width'); itemContext.setProp('x', left); }, positionItemY: function(itemContext, info) { var top = this.getPos(itemContext, info, 'height'); itemContext.setProp('y', top); }, setItemHeight: function(itemContext, info) { var ratio = parseFloat(itemContext.target.height) / 100; itemContext.setHeight(Math.round((info.targetSize.height - info.margins.height) * ratio)); }, setItemWidth: function(itemContext, info) { var ratio = parseFloat(itemContext.target.width) / 100; itemContext.setWidth(Math.round((info.targetSize.width - info.margins.width) * ratio)); } }); Ext.define('Ext.layout.container.Form', { extend: 'Ext.layout.container.Auto', alternateClassName: 'Ext.layout.FormLayout', alias: 'layout.form', type: 'form', formWrapCls: Ext.baseCSSPrefix + 'form-layout-wrap', formWrapAutoLabelCls: Ext.baseCSSPrefix + 'form-layout-auto-label', formWrapSizedLabelCls: Ext.baseCSSPrefix + 'form-layout-sized-label', formColGroupCls: Ext.baseCSSPrefix + 'form-layout-colgroup', formColumnCls: Ext.baseCSSPrefix + 'form-layout-column', formLabelColumnCls: Ext.baseCSSPrefix + 'form-layout-label-column', childEls: [ 'formWrap', 'labelColumn' ], beforeBodyTpl: '
    style="border-spacing:{itemSpacing}px">' + '
    ' + '
    style="width:{labelWidth}">' + '
    ' + '
    ' + '
    ', afterBodyTpl: '
    ', getRenderData: function() { var me = this, labelWidth = me.labelWidth, formWrapCls = me.formWrapCls, data = me.callParent(); if (labelWidth) { if (typeof labelWidth === 'number') { labelWidth += 'px'; } data.labelWidth = labelWidth; formWrapCls += ' ' + me.formWrapSizedLabelCls; } else { formWrapCls += ' ' + me.formWrapAutoLabelCls; } data.formWrapCls = formWrapCls; data.formColGroupCls = me.formColGroupCls; data.formColumnCls = me.formColumnCls; data.formLabelColumnCls = me.formLabelColumnCls; return data; }, getRenderTarget: function() { return this.formWrap; } }); Ext.define('Ext.layout.container.SegmentedButton', { extend: 'Ext.layout.container.Container', alias: 'layout.segmentedbutton', needsItemSize: false, setsItemSize: false, _btnRowCls: Ext.baseCSSPrefix + 'segmented-button-row', getRenderTree: function() { var me = this, result = me.callParent(), i, ln; if (me.owner.getVertical()) { for (i = 0 , ln = result.length; i < ln; i++) { result[i] = { cls: me._btnRowCls, cn: result[i] }; } } return result; }, getItemLayoutEl: function(item) { var dom = item.el.dom; return this.owner.getVertical() ? dom.parentNode : dom; }, onDestroy: function() { if (this.rendered) { var targetEl = this.getRenderTarget(), row; while ((row = targetEl.last())) { row.destroy(); } } } }); Ext.define('Ext.menu.ColorPicker', { extend: 'Ext.menu.Menu', alias: 'widget.colormenu', requires: [ 'Ext.picker.Color' ], hideOnClick: true, pickerId: null, initComponent: function() { var me = this, cfg = Ext.apply({}, me.initialConfig); delete cfg.listeners; Ext.apply(me, { plain: true, showSeparator: false, bodyPadding: 0, items: Ext.applyIf({ cls: Ext.baseCSSPrefix + 'menu-color-item', margin: 0, id: me.pickerId, xtype: 'colorpicker' }, cfg) }); me.callParent(arguments); me.picker = me.down('colorpicker'); me.relayEvents(me.picker, [ 'select' ]); if (me.hideOnClick) { me.on('select', me.hidePickerOnSelect, me); } }, hidePickerOnSelect: function() { Ext.menu.Manager.hideAll(); } }); Ext.define('Ext.menu.DatePicker', { extend: 'Ext.menu.Menu', alias: 'widget.datemenu', requires: [ 'Ext.picker.Date' ], ariaRole: 'dialog', ariaLabel: 'Date picker', hideOnClick: true, pickerId: null, initComponent: function() { var me = this, cfg = Ext.apply({}, me.initialConfig); delete cfg.listeners; Ext.apply(me, { showSeparator: false, plain: true, bodyPadding: 0, items: Ext.applyIf({ cls: Ext.baseCSSPrefix + 'menu-date-item', margin: 0, border: false, id: me.pickerId, xtype: 'datepicker' }, cfg) }); me.callParent(arguments); me.picker = me.down('datepicker'); me.relayEvents(me.picker, [ 'select' ]); if (me.hideOnClick) { me.on('select', me.hidePickerOnSelect, me); } }, hidePickerOnSelect: function() { Ext.menu.Manager.hideAll(); } }); Ext.define('Ext.panel.Pinnable', { extend: 'Ext.Mixin', mixinId: 'pinnable', pinnable: true, pinnedTip: 'Unpin this item', unpinnedTip: 'Pin this item', initPinnable: function() { var me = this, pinned = me.isPinned(); me.addTool(me.pinTool = Ext.widget({ xtype: 'tool', type: pinned ? 'unpin' : 'pin', callback: 'togglePin', scope: me, tooltip: pinned ? me.pinnedTip : me.unpinnedTip })); }, isPinned: function() { return !this.floating; }, setPinned: function(pinned) { var me = this, args; if (pinned !== me.isPinned()) { args = [ me, pinned ]; if (me.fireEventArgs('beforepinchange', args) !== false) { me.updatePinned(pinned); me.fireEventArgs('pinchange', args); } } }, togglePin: function() { this.setPinned(!this.isPinned()); }, updatePinned: function(pinned) { var me = this, tool = me.pinTool; tool.setTooltip(pinned ? me.pinnedTip : me.unpinnedTip); tool.setType(pinned ? 'unpin' : 'pin'); } }); Ext.define('Ext.plugin.Manager', { alternateClassName: [ 'Ext.PluginManager', 'Ext.PluginMgr' ], singleton: true, typeName: 'ptype', create: function(config, defaultType, host) { var result, type; if (config.init) { result = config; } else { if (host) { config = Ext.apply({}, config); config.cmp = host; } else { host = config.cmp; } if (config.xclass) { result = Ext.create(config); } else { type = 'plugin.' + (config.ptype || defaultType); result = Ext.ClassManager.instantiateByAlias(type, config); } } if (result && host && result.setCmp && !result.setCmpCalled) { result.setCmp(host); result.setCmpCalled = true; } return result; } }); Ext.define('Ext.resizer.BorderSplitterTracker', { extend: 'Ext.resizer.SplitterTracker', requires: [ 'Ext.util.Region' ], getPrevCmp: null, getNextCmp: null, calculateConstrainRegion: function() { var me = this, splitter = me.splitter, collapseTarget = splitter.collapseTarget, defaultSplitMin = splitter.defaultSplitMin, sizePropCap = splitter.vertical ? 'Width' : 'Height', minSizeProp = 'min' + sizePropCap, maxSizeProp = 'max' + sizePropCap, getSizeMethod = 'get' + sizePropCap, neighbors = splitter.neighbors, length = neighbors.length, box = collapseTarget.el.getBox(), left = box.x, top = box.y, right = box.right, bottom = box.bottom, size = splitter.vertical ? (right - left) : (bottom - top), i, neighbor, neighborMaxSize, minRange, maxRange, maxGrowth, maxShrink, targetSize; minRange = (collapseTarget[minSizeProp] || Math.min(size, defaultSplitMin)) - size; maxRange = collapseTarget[maxSizeProp]; if (!maxRange) { maxRange = 1000000000; } else { maxRange -= size; } targetSize = size; for (i = 0; i < length; ++i) { neighbor = neighbors[i]; size = neighbor[getSizeMethod](); neighborMaxSize = neighbor[maxSizeProp]; if (neighborMaxSize === null) { neighborMaxSize = undefined; } maxGrowth = size - neighborMaxSize; maxShrink = size - (neighbor[minSizeProp] || Math.min(size, defaultSplitMin)); if (!isNaN(maxGrowth)) { if (minRange < maxGrowth) { minRange = maxGrowth; } } if (maxRange > maxShrink) { maxRange = maxShrink; } } if (maxRange - minRange < 2) { return null; } box = new Ext.util.Region(top, right, bottom, left); me.constraintAdjusters[me.getCollapseDirection()](box, minRange, maxRange, splitter); me.dragInfo = { minRange: minRange, maxRange: maxRange, targetSize: targetSize }; return box; }, constraintAdjusters: { left: function(box, minRange, maxRange, splitter) { box[0] = box.x = box.left = box.right + minRange; box.right += maxRange + splitter.getWidth(); }, top: function(box, minRange, maxRange, splitter) { box[1] = box.y = box.top = box.bottom + minRange; box.bottom += maxRange + splitter.getHeight(); }, bottom: function(box, minRange, maxRange, splitter) { box.bottom = box.top - minRange; box.top -= maxRange + splitter.getHeight(); }, right: function(box, minRange, maxRange, splitter) { box.right = box.left - minRange; box[0] = box.x = box.left = box.x - maxRange + splitter.getWidth(); } }, onBeforeStart: function(e) { var me = this, splitter = me.splitter, collapseTarget = splitter.collapseTarget, neighbors = splitter.neighbors, length = neighbors.length, i, neighbor; if (collapseTarget.collapsed) { return false; } for (i = 0; i < length; ++i) { neighbor = neighbors[i]; if (neighbor.collapsed && neighbor.isHorz === collapseTarget.isHorz) { return false; } } if (!(me.constrainTo = me.calculateConstrainRegion())) { return false; } return true; }, performResize: function(e, offset) { var me = this, splitter = me.splitter, collapseDirection = splitter.getCollapseDirection(), collapseTarget = splitter.collapseTarget, adjusters = me.splitAdjusters[splitter.vertical ? 'horz' : 'vert'], delta = offset[adjusters.index], dragInfo = me.dragInfo, owner; if (collapseDirection === 'right' || collapseDirection === 'bottom') { delta = -delta; } delta = Math.min(Math.max(dragInfo.minRange, delta), dragInfo.maxRange); if (delta) { (owner = splitter.ownerCt).suspendLayouts(); adjusters.adjustTarget(collapseTarget, dragInfo.targetSize, delta); owner.resumeLayouts(true); } }, splitAdjusters: { horz: { index: 0, adjustTarget: function(target, size, delta) { target.flex = null; target.setSize(size + delta); } }, vert: { index: 1, adjustTarget: function(target, targetSize, delta) { target.flex = null; target.setSize(undefined, targetSize + delta); } } }, getCollapseDirection: function() { return this.splitter.getCollapseDirection(); } }); Ext.define('Ext.resizer.Handle', { extend: 'Ext.Component', handleCls: '', baseHandleCls: Ext.baseCSSPrefix + 'resizable-handle', region: '', ariaRole: 'presentation', beforeRender: function() { var me = this; me.callParent(); me.protoEl.unselectable(); me.addCls(me.baseHandleCls, me.baseHandleCls + '-' + me.region, me.handleCls); } }); Ext.define('Ext.resizer.ResizeTracker', { extend: 'Ext.dd.DragTracker', dynamic: true, preserveRatio: false, constrainTo: null, proxyCls: Ext.baseCSSPrefix + 'resizable-proxy', constructor: function(config) { var me = this, widthRatio, heightRatio, throttledResizeFn; if (!config.el) { if (config.target.isComponent) { me.el = config.target.getEl(); } else { me.el = config.target; } } this.callParent(arguments); if (me.preserveRatio && me.minWidth && me.minHeight) { 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; } } if (me.throttle) { 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); } }; } }, onBeforeStart: function(e) { this.startBox = this.target.getBox(); }, getProxy: function() { var me = this; if (!me.dynamic && !me.proxy) { me.proxy = me.createProxy(me.target || me.el); me.hideProxy = true; } if (me.proxy) { me.proxy.show(); return me.proxy; } }, createProxy: function(target) { var proxy, cls = this.proxyCls; if (target.isComponent) { proxy = target.getProxy().addCls(cls); } else { proxy = target.createProxy({ tag: 'div', role: 'presentation', cls: cls, id: target.id + '-rzproxy' }, Ext.getBody()); } proxy.removeCls(Ext.baseCSSPrefix + 'proxy-el'); return proxy; }, onStart: function(e) { this.activeResizeHandle = Ext.get(this.getDragTarget().id); if (!this.dynamic) { this.resize(this.startBox); } }, onDrag: function(e) { if (this.dynamic || this.proxy) { this.updateDimensions(e); } }, 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, snappedWidth, snappedHeight, adjustX = 0, adjustY = 0, dragRatio, oppositeCorner, axis, newBox, newHeight, newWidth; region = me.convertRegionName(region); 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; } newBox = { width: box.width + widthAdjust, height: box.height + heightAdjust, x: box.x + adjustX, y: box.y + adjustY }; snappedWidth = Ext.Number.snap(newBox.width, me.widthIncrement); snappedHeight = Ext.Number.snap(newBox.height, me.heightIncrement); if (snappedWidth !== newBox.width || snappedHeight !== newBox.height) { switch (region) { case 'northeast': newBox.y -= snappedHeight - newBox.height; break; case 'north': newBox.y -= snappedHeight - newBox.height; break; case 'southwest': newBox.x -= snappedWidth - newBox.width; break; case 'west': newBox.x -= snappedWidth - newBox.width; break; case 'northwest': newBox.x -= snappedWidth - newBox.width; newBox.y -= snappedHeight - newBox.height; } newBox.width = snappedWidth; newBox.height = snappedHeight; } if (newBox.width < me.minWidth || newBox.width > me.maxWidth) { newBox.width = Ext.Number.constrain(newBox.width, me.minWidth, me.maxWidth); if (adjustX) { newBox.x = box.x + (box.width - newBox.width); } } else { me.lastX = newBox.x; } if (newBox.height < me.minHeight || newBox.height > me.maxHeight) { newBox.height = Ext.Number.constrain(newBox.height, me.minHeight, me.maxHeight); if (adjustY) { newBox.y = box.y + (box.height - newBox.height); } } else { me.lastY = newBox.y; } if (me.preserveRatio || e.shiftKey) { ratio = me.startBox.width / me.startBox.height; newHeight = Math.min(Math.max(me.minHeight, newBox.width / ratio), me.maxHeight); newWidth = Math.min(Math.max(me.minWidth, newBox.height * ratio), me.maxWidth); if (axis === 1) { newBox.height = newHeight; } else if (axis === 2) { newBox.width = newWidth; } else { dragRatio = Math.abs(oppositeCorner[0] - this.lastXY[0]) / Math.abs(oppositeCorner[1] - this.lastXY[1]); if (dragRatio > ratio) { newBox.height = newHeight; } else { newBox.width = newWidth; } 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); } } } me.setPosition = newBox.x !== me.startBox.x || newBox.y !== me.startBox.y; me.resize(newBox, atEnd); }, resize: function(box, atEnd) { var me = this, target, setPosition = me.setPosition; if (me.dynamic || (!me.dynamic && atEnd)) { if (setPosition) { me.target.setBox(box); } else { me.target.setSize(box.width, box.height); } } if (!atEnd) { target = me.getProxy(); if (target && target !== me.target) { if (setPosition || me.hideProxy) { target.setBox(box); } else { target.setSize(box.width, box.height); } } } }, onEnd: function(e) { this.updateDimensions(e, true); if (this.proxy && this.hideProxy) { this.proxy.hide(); } }, convertRegionName: function(name) { return name; } }); Ext.define('Ext.resizer.Resizer', { mixins: { observable: 'Ext.util.Observable' }, uses: [ 'Ext.resizer.ResizeTracker', 'Ext.Component' ], alternateClassName: 'Ext.Resizable', handleCls: Ext.baseCSSPrefix + 'resizable-handle', overCls: Ext.baseCSSPrefix + 'resizable-handle-over', pinnedCls: Ext.baseCSSPrefix + 'resizable-pinned', wrapCls: Ext.baseCSSPrefix + 'resizable-wrap', wrappedCls: Ext.baseCSSPrefix + 'resizable-wrapped', delimiterRe: /(?:\s*[,;]\s*)|\s+/, dynamic: true, handles: 's e se', height: null, width: null, heightIncrement: 0, widthIncrement: 0, minHeight: 20, minWidth: 20, maxHeight: 10000, maxWidth: 10000, pinned: false, preserveRatio: false, transparent: false, possiblePositions: { n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast' }, ariaRole: 'presentation', constructor: function(config) { var me = this, handles = me.handles, unselectableCls = Ext.dom.Element.unselectableCls, handleEls = [], resizeTarget, handleCls, possibles, tag, len, i, pos, el, box, wrapTarget, positioning, targetBaseCls; if (Ext.isString(config) || Ext.isElement(config) || config.dom) { resizeTarget = config; config = arguments[1] || {}; config.target = resizeTarget; } me.mixins.observable.constructor.call(me, config); resizeTarget = me.target; if (resizeTarget) { if (resizeTarget.isComponent) { resizeTarget.addClsWithUI('resizable'); if (resizeTarget.minWidth) { me.minWidth = resizeTarget.minWidth; } if (resizeTarget.minHeight) { me.minHeight = resizeTarget.minHeight; } if (resizeTarget.maxWidth) { me.maxWidth = resizeTarget.maxWidth; } if (resizeTarget.maxHeight) { me.maxHeight = resizeTarget.maxHeight; } if (resizeTarget.floating) { if (!me.hasOwnProperty('handles')) { me.handles = 'n ne e se s sw w nw'; } } me.el = resizeTarget.getEl(); } else { resizeTarget = me.el = me.target = Ext.get(resizeTarget); } } else { resizeTarget = me.target = me.el = Ext.get(me.el); } me.el.addCls(Ext.Component.prototype.borderBoxCls); if (Ext.isNumber(me.width)) { me.width = Ext.Number.constrain(me.width, me.minWidth, me.maxWidth); } if (Ext.isNumber(me.height)) { me.height = Ext.Number.constrain(me.height, me.minHeight, me.maxHeight); } if (me.width !== null || me.height !== null) { me.target.setSize(me.width, me.height); } tag = me.el.dom.tagName.toUpperCase(); if (tag === 'TEXTAREA' || tag === 'IMG' || tag === 'TABLE') { me.originalTarget = me.target; wrapTarget = resizeTarget.isComponent ? resizeTarget.getEl() : resizeTarget; me.el.addCls(me.wrappedCls); me.target = me.el = me.el.wrap({ role: 'presentation', cls: me.wrapCls, id: me.el.id + '-rzwrap', style: wrapTarget.getStyle([ 'margin-top', 'margin-bottom' ]) }); positioning = wrapTarget.getPositioning(); me.el.setPositioning(positioning); wrapTarget.clearPositioning(); box = wrapTarget.getBox(); if (positioning.position !== 'absolute') { box.x = 0; box.y = 0; } me.el.setBox(box); wrapTarget.setStyle('position', 'absolute'); me.isTargetWrapped = true; } me.el.position(); if (me.pinned) { me.el.addCls(me.pinnedCls); } me.resizeTracker = new Ext.resizer.ResizeTracker({ disabled: me.disabled, target: resizeTarget, el: me.el, constrainTo: me.constrainTo, handleCls: me.handleCls, overCls: me.overCls, throttle: me.throttle, proxy: me.originalTarget ? me.el : null, dynamic: me.originalTarget ? true : me.dynamic, originalTarget: me.originalTarget, delegate: '.' + me.handleCls, preserveRatio: me.preserveRatio, heightIncrement: me.heightIncrement, widthIncrement: me.widthIncrement, minHeight: me.minHeight, maxHeight: me.maxHeight, minWidth: me.minWidth, maxWidth: me.maxWidth }); me.resizeTracker.on({ mousedown: me.onBeforeResize, drag: me.onResize, dragend: me.onResizeEnd, scope: me }); if (me.handles === 'all') { me.handles = 'n s e w ne nw se sw'; } handles = me.handles = me.handles.split(me.delimiterRe); possibles = me.possiblePositions; len = handles.length; handleCls = me.handleCls + ' ' + me.handleCls + '-{0}'; if (me.target.isComponent) { targetBaseCls = me.target.baseCls; handleCls += ' ' + targetBaseCls + '-handle ' + targetBaseCls + '-handle-{0}'; if (Ext.supports.CSS3BorderRadius) { handleCls += ' ' + targetBaseCls + '-handle-{0}-br'; } } for (i = 0; i < len; i++) { if (handles[i] && possibles[handles[i]]) { pos = possibles[handles[i]]; handleEls.push(''); } } Ext.DomHelper.append(me.el, handleEls.join('')); handleEls.length = 0; for (i = 0; i < len; i++) { if (handles[i] && possibles[handles[i]]) { pos = possibles[handles[i]]; el = me[pos] = me.el.getById(me.el.id + '-' + pos + '-handle'); handleEls.push(el); el.region = pos; if (me.transparent) { el.setOpacity(0); } } } me.resizeTracker.handleEls = handleEls; }, disable: function() { this.resizeTracker.disable(); }, enable: function() { this.resizeTracker.enable(); }, onBeforeResize: function(tracker, e) { return this.fireResizeEvent('beforeresize', tracker, e); }, onResize: function(tracker, e) { return this.fireResizeEvent('resizedrag', tracker, e); }, onResizeEnd: function(tracker, e) { return this.fireResizeEvent('resize', tracker, e); }, fireResizeEvent: function(name, tracker, e) { var me = this, box; if (me.hasListeners[name]) { box = me.el.getBox(); return me.fireEvent(name, me, box.width, box.height, e); } }, resizeTo: function(width, height) { var me = this; me.target.setSize(width, height); me.fireEvent('resize', me, width, height, null); }, getEl: function() { return this.el; }, getTarget: function() { return this.target; }, destroy: function() { var me = this, i, handles = me.handles, len = handles.length, positions = me.possiblePositions, handle; me.resizeTracker.destroy(); if (me.isTargetWrapped) { me.target.destroy(); } for (i = 0; i < len; i++) { if ((handle = me[positions[handles[i]]])) { handle.destroy(); } } } }); Ext.define('Ext.selection.CellModel', { extend: 'Ext.selection.DataViewModel', alias: 'selection.cellmodel', requires: [ 'Ext.grid.CellContext' ], isCellModel: true, deselectOnContainerClick: false, enableKeyNav: true, preventWrap: false, bindComponent: function(view) { var me = this, grid; if (me.view && me.gridListeners) { me.gridListeners.destroy(); } me.callParent([ view ]); if (view) { grid = view.grid || view.ownerCt; if (grid.optimizedColumnMove !== false) { me.gridListeners = grid.on({ columnmove: me.onColumnMove, scope: me, destroyable: true }); } } }, getViewListeners: function() { var result = this.callParent(); result.refresh = this.onViewRefresh; return result; }, getHeaderCt: function() { var selection = this.navigationModel.getPosition(), view = selection ? selection.view : this.primaryView; return view.headerCt; }, onNavigate: function(e) { if (!e.record) { return; } this.setPosition(e.position); }, selectWithEvent: function(record, e) { this.select(record); }, select: function(pos, keepExisting, suppressEvent) { var me = this, row, oldPos = me.getPosition(), store = me.view.store; if (pos || pos === 0) { if (pos.isModel) { row = store.indexOf(pos); if (row !== -1) { pos = { row: row, column: oldPos ? oldPos.column : 0 }; } else { pos = null; } } else if (typeof pos === 'number') { pos = { row: pos, column: 0 }; } } if (pos) { me.selectByPosition(pos, suppressEvent); } else { me.deselect(); } }, getCurrentPosition: function() { var position = this.selecting ? this.nextSelection : this.selection; return position ? { view: position.view, record: position.record, row: position.rowIdx, columnHeader: position.column, column: position.view.getColumnManager().indexOf(position.column) } : position; }, getPosition: function() { return (this.selecting ? this.nextSelection : this.selection) || null; }, setCurrentPosition: function(pos, suppressEvent, preventCheck) { if (pos && !pos.isCellContext) { pos = new Ext.grid.CellContext(this.view).setPosition({ row: pos.row, column: typeof pos.column === 'number' ? this.view.getColumnManager().getColumns()[pos.column] : pos.column }); } return this.setPosition(pos, suppressEvent, preventCheck); }, setPosition: function(pos, suppressEvent, preventCheck) { var me = this, last = me.selection; if (pos) { pos = pos.isCellContext ? pos.clone() : new Ext.grid.CellContext(me.view).setPosition(pos); } if (!preventCheck && last) { if (pos && (pos.record === last.record && pos.column === last.column && pos.view === last.view)) { pos = null; } else { me.onCellDeselect(me.selection, suppressEvent); } } if (pos) { me.nextSelection = pos; me.selecting = true; me.onCellSelect(me.nextSelection, suppressEvent); me.selecting = false; return (me.selection = pos); } return null; }, isCellSelected: function(view, row, column) { var me = this, testPos, pos = me.getPosition(); if (pos && pos.view === view) { testPos = new Ext.grid.CellContext(view).setPosition({ row: row, column: typeof column === 'number' ? view.getColumnManager().getColumns()[column] : column }); return (testPos.record === pos.record) && (testPos.column === pos.column); } }, onStoreRemove: function(store, records, indices) { var me = this, pos = me.getPosition(); me.callParent(arguments); if (pos && store.isMoving(pos.record)) { return; } if (pos && store.getCount() && store.indexOf(pos.record) !== -1) { pos.setRow(pos.record); } else { me.selection = null; } }, onStoreClear: function() { this.callParent(arguments); this.selection = null; }, onStoreAdd: function() { var me = this, pos = me.getPosition(); me.callParent(arguments); if (pos) { pos.setRow(pos.record); } else { me.selection = null; } }, onCellClick: function(view, cell, cellIndex, record, row, recordIndex, e) { if (recordIndex !== -1) { this.setPosition(e.position); } }, onCellSelect: function(position, supressEvent) { if (position && position.rowIdx !== undefined && position.rowIdx > -1) { this.doSelect(position.record, false, supressEvent); } }, onCellDeselect: function(position, supressEvent) { if (position && position.rowIdx !== undefined) { this.doDeselect(position.record, supressEvent); } }, onSelectChange: function(record, isSelected, suppressEvent, commitFn) { var me = this, pos, eventName, view; if (isSelected) { pos = me.nextSelection; eventName = 'select'; } else { pos = me.selection; eventName = 'deselect'; } view = pos.view || me.primaryView; if ((suppressEvent || me.fireEvent('before' + eventName, me, record, pos.rowIdx, pos.colIdx)) !== false && commitFn() !== false) { if (isSelected) { view.onCellSelect(pos); } else { view.onCellDeselect(pos); delete me.selection; } if (!suppressEvent) { me.fireEvent(eventName, me, record, pos.rowIdx, pos.colIdx); } } }, onEditorTab: function(editingPlugin, e) { var me = this, direction = e.shiftKey ? 'left' : 'right', pos = e.position, position = pos.view.walkCells(pos, direction, e, me.preventWrap); if (position) { if (editingPlugin.startEdit(position.record, position.column)) { me.wasEditing = false; } else { position.view.getNavigationModel().setPosition(position, null, e); me.wasEditing = true; } } }, refresh: function() { var pos = this.getPosition(), selRowIdx; if (pos && (selRowIdx = this.store.indexOf(this.selected.last())) !== -1) { pos.rowIdx = selRowIdx; } }, onColumnMove: function(headerCt, header, fromIdx, toIdx) { var grid = headerCt.up('tablepanel'); if (grid) { this.onViewRefresh(grid.view); } }, onUpdate: function(record) { var me = this, pos; if (me.isSelected(record)) { pos = me.selecting ? me.nextSelection : me.selection; me.view.onCellSelect(pos); } }, onViewRefresh: function(view) { var me = this, pos = me.getPosition(), newPos, headerCt = view.headerCt, record, column; if (pos && pos.view === view) { record = pos.record; column = pos.column; if (!column.isDescendantOf(headerCt)) { column = headerCt.queryById(column.id) || headerCt.down('[text="' + column.text + '"]') || headerCt.down('[dataIndex="' + column.dataIndex + '"]'); } if (pos.record) { if (column && (view.store.indexOfId(record.getId()) !== -1)) { newPos = new Ext.grid.CellContext(view).setPosition({ row: record, column: column }); me.setPosition(newPos); } } else { me.selection = null; } } }, selectByPosition: function(position, suppressEvent) { this.setPosition(position, suppressEvent); } }); Ext.define('Ext.selection.CheckboxModel', { alias: 'selection.checkboxmodel', extend: 'Ext.selection.RowModel', mode: 'MULTI', injectCheckbox: 0, checkOnly: false, showHeaderCheckbox: undefined, checkSelector: '.' + Ext.baseCSSPrefix + 'grid-row-checker', allowDeselect: true, headerWidth: 24, checkerOnCls: Ext.baseCSSPrefix + 'grid-hd-checker-on', tdCls: Ext.baseCSSPrefix + 'grid-cell-special ' + Ext.baseCSSPrefix + 'grid-cell-row-checker', constructor: function() { var me = this; me.callParent(arguments); if (me.mode === 'SINGLE' && me.showHeaderCheckbox !== true) { me.showHeaderCheckbox = false; } }, beforeViewRender: function(view) { var me = this, owner; me.callParent(arguments); if (!me.hasLockedHeader() || view.headerCt.lockedCt) { me.addCheckbox(view, true); owner = view.ownerCt; if (view.headerCt.lockedCt) { owner = owner.ownerCt; } me.mon(owner, 'reconfigure', me.onReconfigure, me); } }, bindComponent: function(view) { this.sortable = false; this.callParent(arguments); }, hasLockedHeader: function() { var views = this.views, vLen = views.length, v; for (v = 0; v < vLen; v++) { if (views[v].headerCt.lockedCt) { return true; } } return false; }, addCheckbox: function(view, initial) { var me = this, checkbox = me.injectCheckbox, headerCt = view.headerCt; if (checkbox !== false) { if (checkbox === 'first') { checkbox = 0; } else if (checkbox === 'last') { checkbox = headerCt.getColumnCount(); } Ext.suspendLayouts(); if (view.getStore().isBufferedStore) { me.showHeaderCheckbox = false; } me.column = headerCt.add(checkbox, me.getHeaderConfig()); Ext.resumeLayouts(); } if (initial !== true) { view.refresh(); } }, onReconfigure: function(grid, store, columns) { if (columns) { this.addCheckbox(this.views[0]); } }, toggleUiHeader: function(isChecked) { var view = this.views[0], headerCt = view.headerCt, checkHd = headerCt.child('gridcolumn[isCheckerHd]'), cls = this.checkerOnCls; if (checkHd) { if (isChecked) { checkHd.addCls(cls); } else { checkHd.removeCls(cls); } } }, onHeaderClick: function(headerCt, header, e) { if (header === this.column) { e.stopEvent(); var me = this, isChecked = header.el.hasCls(Ext.baseCSSPrefix + 'grid-hd-checker-on'); if (isChecked) { me.deselectAll(); } else { me.selectAll(); } } }, getHeaderConfig: function() { var me = this, showCheck = me.showHeaderCheckbox !== false; return { xtype: 'gridcolumn', isCheckerHd: showCheck, text: ' ', clickTargetName: 'el', width: me.headerWidth, sortable: false, draggable: false, resizable: false, hideable: false, menuDisabled: true, dataIndex: '', tdCls: me.tdCls, cls: showCheck ? Ext.baseCSSPrefix + 'column-header-checkbox ' : '', defaultRenderer: me.renderer.bind(me), editRenderer: me.editRenderer || me.renderEmpty, locked: me.hasLockedHeader() }; }, renderEmpty: function() { return ' '; }, refresh: function() { this.callParent(arguments); this.updateHeaderState(); }, renderer: function(value, metaData, record, rowIndex, colIndex, store, view) { return ''; }, selectByPosition: function(position, keepExisting) { if (!position.isCellContext) { position = new Ext.grid.CellContext(this.view).setPosition(position.row, position.column); } if (!this.checkOnly || position.column !== this.column) { this.callParent([ position, keepExisting ]); } }, onSelectChange: function() { this.callParent(arguments); if (!this.suspendChange) { this.updateHeaderState(); } }, onStoreLoad: function() { this.callParent(arguments); this.updateHeaderState(); }, onStoreAdd: function() { this.callParent(arguments); this.updateHeaderState(); }, onStoreRemove: function() { this.callParent(arguments); this.updateHeaderState(); }, onStoreRefresh: function() { this.callParent(arguments); this.updateHeaderState(); }, maybeFireSelectionChange: function(fireEvent) { if (fireEvent && !this.suspendChange) { this.updateHeaderState(); } this.callParent(arguments); }, resumeChanges: function() { this.callParent(); if (!this.suspendChange) { this.updateHeaderState(); } }, updateHeaderState: function() { var me = this, store = me.store, storeCount = store.getCount(), views = me.views, hdSelectStatus = false, selectedCount = 0, selected, len, i; if (!store.isBufferedStore && storeCount > 0) { selected = me.selected; hdSelectStatus = true; for (i = 0 , len = selected.getCount(); i < len; ++i) { if (store.indexOfId(selected.getAt(i).id) === -1) { break; } ++selectedCount; } hdSelectStatus = storeCount === selectedCount; } if (views && views.length) { me.toggleUiHeader(hdSelectStatus); } }, vetoSelection: function(e) { var me = this, column = me.column, veto, isClick, isSpace; if (me.checkOnly) { isClick = e.type === 'click' && e.getTarget(me.checkSelector); isSpace = e.getKey() === e.SPACE && e.position.column === column; veto = !(isClick || isSpace); } return veto || me.callParent([ e ]); }, destroy: function() { this.column = null; this.callParent(); }, privates: { onBeforeNavigate: function(metaEvent) { var e = metaEvent.keyEvent; if (this.selectionMode !== 'SINGLE') { metaEvent.ctrlKey = metaEvent.ctrlKey || e.ctrlKey || (e.type === 'click' && !e.shiftKey) || e.getKey() === e.SPACE; } }, selectWithEventMulti: function(record, e, isSelected) { var me = this; if (!e.shiftKey && !e.ctrlKey && e.getTarget(me.checkSelector)) { if (isSelected) { me.doDeselect(record); } else { me.doSelect(record, true); } } else { me.callParent([ record, e, isSelected ]); } } } }); Ext.define('Ext.slider.Thumb', { requires: [ 'Ext.dd.DragTracker', 'Ext.util.Format' ], overCls: Ext.baseCSSPrefix + 'slider-thumb-over', constructor: function(config) { var me = this; Ext.apply(me, config || {}, { cls: Ext.baseCSSPrefix + 'slider-thumb', constrain: false }); me.callParent([ config ]); }, render: function() { var me = this; me.el = me.slider.innerEl.insertFirst(me.getElConfig()); me.onRender(); }, onRender: function() { if (this.disabled) { this.disable(); } this.initEvents(); }, getElConfig: function() { var me = this, slider = me.slider, style = {}; style[slider.vertical ? 'bottom' : slider.horizontalProp] = slider.calculateThumbPosition(slider.normalizeValue(me.value)) + '%'; return { style: style, id: this.id, cls: this.cls, role: 'presentation' }; }, move: function(v, animate) { var me = this, el = me.el, slider = me.slider, styleProp = slider.vertical ? 'bottom' : slider.horizontalProp, to, from, animCfg; v += '%'; if (!animate) { el.dom.style[styleProp] = v; } else { to = {}; to[styleProp] = v; if (!Ext.supports.GetPositionPercentage) { from = {}; from[styleProp] = el.dom.style[styleProp]; } animCfg = { target: el, duration: 350, from: from, to: to, scope: me, callback: me.onAnimComplete }; if (animate !== true) { Ext.apply(animCfg, animate); } me.anim = new Ext.fx.Anim(animCfg); } }, onAnimComplete: function() { this.anim = null; }, enable: function() { var el = this.el; this.disabled = false; if (el) { el.removeCls(this.slider.disabledCls); } }, disable: function() { var el = this.el; this.disabled = true; if (el) { el.addCls(this.slider.disabledCls); } }, initEvents: function() { var me = this; me.tracker = new Ext.dd.DragTracker({ el: me.el, onBeforeStart: me.onBeforeDragStart.bind(me), onStart: me.onDragStart.bind(me), onDrag: me.onDrag.bind(me), onEnd: me.onDragEnd.bind(me), tolerance: 3, autoStart: 300 }); me.el.hover(me.addOverCls, me.removeOverCls, me); }, addOverCls: function() { var me = this; if (!me.disabled) { me.el.addCls(me.overCls); } }, removeOverCls: function() { this.el.removeCls(this.overCls); }, onBeforeDragStart: function(e) { var me = this, el = me.el, trackerXY = me.tracker.getXY(), delta = me.pointerOffset = el.getXY(); if (me.disabled) { return false; } else { delta[0] += Math.floor(el.getWidth() / 2) - trackerXY[0]; delta[1] += Math.floor(el.getHeight() / 2) - trackerXY[1]; me.slider.promoteThumb(me); return true; } }, onDragStart: function(e) { var me = this, slider = me.slider; slider.onDragStart(me, e); me.el.addCls(Ext.baseCSSPrefix + 'slider-thumb-drag'); me.dragging = me.slider.dragging = true; me.dragStartValue = me.value; slider.fireEvent('dragstart', slider, e, me); }, onDrag: function(e) { var me = this, slider = me.slider, index = me.index, newValue = me.getValueFromTracker(), above, below; if (newValue !== undefined) { 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); } }, getValueFromTracker: function() { var slider = this.slider, trackerXY = this.tracker.getXY(), trackPoint; trackerXY[0] += this.pointerOffset[0]; trackerXY[1] += this.pointerOffset[1]; trackPoint = slider.getTrackpoint(trackerXY); if (trackPoint !== undefined) { return slider.reversePixelValue(trackPoint); } }, onDragEnd: function(e) { var me = this, slider = me.slider, value = me.value; slider.onDragEnd(me, e); me.el.removeCls(Ext.baseCSSPrefix + 'slider-thumb-drag'); me.dragging = slider.dragging = false; slider.fireEvent('dragend', slider, e); if (me.dragStartValue !== value) { slider.fireEvent('changecomplete', slider, value, me); } }, destroy: function() { var me = this, anim = this.anim; if (anim) { anim.end(); } me.el = me.tracker = me.anim = Ext.destroy(me.el, me.tracker); } }); Ext.define('Ext.slider.Tip', { extend: 'Ext.tip.Tip', minWidth: 10, alias: 'widget.slidertip', offsets: null, align: null, position: '', defaultVerticalPosition: 'left', defaultHorizontalPosition: 'top', isSliderTip: true, init: function(slider) { var me = this, align, offsets; if (!me.position) { me.position = slider.vertical ? me.defaultVerticalPosition : me.defaultHorizontalPosition; } switch (me.position) { case 'top': offsets = [ 0, -10 ]; align = 'b-t?'; break; case 'bottom': offsets = [ 0, 10 ]; align = 't-b?'; break; case 'left': offsets = [ -10, 0 ]; align = 'r-l?'; break; case 'right': offsets = [ 10, 0 ]; align = 'l-r?'; } if (!me.align) { me.align = align; } if (!me.offsets) { me.offsets = offsets; } 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.el.alignTo(thumb.el, me.align, me.offsets); }, getText: function(thumb) { return String(thumb.value); } }); 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' ], focusable: true, needArrowKeys: true, tabIndex: 0, focusCls: 'slider-focus', childEls: [ 'endEl', 'innerEl' ], fieldSubTpl: [ '
    tabindex="{tabIdx}"', ' aria-orientation="vertical" aria-orientation="horizontal"', '>', '', '
    ', { renderThumbs: function(out, values) { var me = values.$comp, i = 0, thumbs = me.thumbs, len = thumbs.length, thumb, thumbConfig; for (; i < len; i++) { thumb = thumbs[i]; thumbConfig = thumb.getElConfig(); thumbConfig.id = me.id + '-thumb-' + i; Ext.DomHelper.generateMarkup(thumbConfig, out); } }, disableFormats: true } ], horizontalProp: 'left', vertical: false, minValue: 0, maxValue: 100, decimalPrecision: 0, keyIncrement: 1, increment: 0, clickRange: [ 5, 15 ], clickToChange: true, animate: true, dragging: false, constrainThumbs: true, useTips: true, tipText: null, ariaRole: 'slider', defaultBindProperty: 'values', initValue: function() { var me = this, extValueFrom = Ext.valueFrom, values = extValueFrom(me.values, [ extValueFrom(me.value, extValueFrom(me.minValue, 0)) ]), i = 0, len = values.length; me.originalValue = values; for (; i < len; i++) { me.addThumb(me.normalizeValue(values[i])); } }, initComponent: function() { var me = this, tipPlug, hasTip, p, pLen, plugins; me.thumbs = []; me.keyIncrement = Math.max(me.increment, me.keyIncrement); me.extraFieldBodyCls = Ext.baseCSSPrefix + 'slider-ct-' + (me.vertical ? 'vert' : 'horz'); me.callParent(); if (me.useTips) { if (Ext.isObject(me.useTips)) { tipPlug = Ext.apply({}, me.useTips); } else { tipPlug = me.tipText ? { getText: me.tipText } : {}; } plugins = me.plugins = me.plugins || []; pLen = plugins.length; for (p = 0; p < pLen; p++) { if (plugins[p].isSliderTip) { hasTip = true; break; } } if (!hasTip) { me.plugins.push(new Ext.slider.Tip(tipPlug)); } } }, addThumb: function(value) { var me = this, thumb = new Ext.slider.Thumb({ ownerCt: me, value: value, slider: me, index: me.thumbs.length, constrain: me.constrainThumbs, disabled: !!me.readOnly }); me.thumbs.push(thumb); if (me.rendered) { thumb.render(); } return thumb; }, promoteThumb: function(topThumb) { var thumbs = this.thumbStack || (this.thumbStack = Ext.Array.slice(this.thumbs)), ln = thumbs.length, zIndex = 10000, i; if (thumbs[0] !== topThumb) { Ext.Array.remove(thumbs, topThumb); thumbs.unshift(topThumb); } for (i = 0; i < ln; i++) { thumbs[i].el.setStyle('zIndex', zIndex); zIndex -= 1000; } }, getSubTplData: function(fieldData) { var me = this; return Ext.apply(me.callParent(arguments), { $comp: me, isVertical: me.vertical, vertical: me.vertical ? Ext.baseCSSPrefix + 'slider-vert' : Ext.baseCSSPrefix + 'slider-horz', minValue: me.minValue, maxValue: me.maxValue, value: me.value, tabIdx: me.tabIndex, childElCls: '' }); }, onRender: function() { var me = this, thumbs = me.thumbs, len = thumbs.length, i = 0, thumb; me.callParent(arguments); for (i = 0; i < len; i++) { thumb = thumbs[i]; thumb.el = me.el.getById(me.id + '-thumb-' + i); thumb.onRender(); } }, initEvents: function() { var me = this; me.callParent(); me.mon(me.el, { scope: me, mousedown: me.onMouseDown, keydown: me.onKeyDown }); }, onDragStart: Ext.emptyFn, onDragEnd: Ext.emptyFn, getTrackpoint: function(xy) { var me = this, vertical = me.vertical, sliderTrack = me.innerEl, trackLength, result, positionProperty; if (vertical) { positionProperty = 'top'; trackLength = sliderTrack.getHeight(); } else { positionProperty = me.horizontalProp; trackLength = sliderTrack.getWidth(); } xy = me.transformTrackPoints(sliderTrack.translatePoints(xy)); result = Ext.Number.constrain(xy[positionProperty], 0, trackLength); return vertical ? trackLength - result : result; }, transformTrackPoints: Ext.identityFn, checkChange: Ext.emptyFn, onMouseDown: function(e) { var me = this, thumbClicked = false, i = 0, thumbs = me.thumbs, len = thumbs.length, trackPoint; if (me.disabled) { return; } for (; !thumbClicked && i < len; i++) { thumbClicked = thumbClicked || e.target === thumbs[i].el.dom; } if (me.clickToChange && !thumbClicked) { trackPoint = me.getTrackpoint(e.getXY()); if (trackPoint !== undefined) { me.onClickChange(trackPoint); } } me.focus(); }, onClickChange: function(trackPoint) { var me = this, thumb, index; thumb = me.getNearest(trackPoint); if (!thumb.disabled) { index = thumb.index; me.setValue(index, Ext.util.Format.round(me.reversePixelValue(trackPoint), me.decimalPrecision), undefined, true); } }, getNearest: function(trackPoint) { var me = this, clickValue = me.reversePixelValue(trackPoint), nearestDistance = me.getRange() + 5, 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; nearestDistance = dist; } } return nearest; }, onKeyDown: function(e) { var me = this, k, val; if (me.disabled || me.thumbs.length !== 1) { e.preventDefault(); return; } k = e.getKey(); switch (k) { case e.UP: case e.RIGHT: 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; } }, normalizeValue: function(v) { var me = this, snapFn = me.zeroBasedSnapping ? 'snap' : 'snapInRange'; v = Ext.Number[snapFn](v, me.increment, me.minValue, me.maxValue); v = Ext.util.Format.round(v, me.decimalPrecision); v = Ext.Number.constrain(v, me.minValue, me.maxValue); return v; }, setMinValue: function(val) { var me = this, thumbs = me.thumbs, len = thumbs.length, thumb, i; me.minValue = val; for (i = 0; i < len; ++i) { thumb = thumbs[i]; if (thumb.value < val) { me.setValue(i, val, false); } } me.syncThumbs(); }, setMaxValue: function(val) { var me = this, thumbs = me.thumbs, len = thumbs.length, thumb, i; me.maxValue = val; for (i = 0; i < len; ++i) { thumb = thumbs[i]; if (thumb.value > val) { me.setValue(i, val, false); } } me.syncThumbs(); }, setValue: function(index, value, animate, changeComplete) { var me = this, thumbs = me.thumbs, thumb, len, i, values; if (Ext.isArray(index)) { values = index; animate = value; for (i = 0 , len = values.length; i < len; ++i) { thumb = thumbs[i]; if (thumb) { me.setValue(i, values[i], animate); } } return me; } thumb = me.thumbs[index]; value = me.normalizeValue(value); if (value !== thumb.value && me.fireEvent('beforechange', me, value, thumb.value, thumb) !== false) { thumb.value = value; if (me.rendered) { if (Ext.isDefined(animate)) { animate = animate === false ? false : animate; } else { animate = me.animate; } thumb.move(me.calculateThumbPosition(value), animate); me.fireEvent('change', me, value, thumb); me.checkDirty(); if (changeComplete) { me.fireEvent('changecomplete', me, value, thumb); } } } return me; }, calculateThumbPosition: function(v) { var me = this, minValue = me.minValue, pos = (v - minValue) / me.getRange() * 100; if (isNaN(pos)) { pos = 0; } return pos; }, getRatio: function() { var me = this, innerEl = me.innerEl, trackLength = me.vertical ? innerEl.getHeight() : innerEl.getWidth(), valueRange = me.getRange(); return valueRange === 0 ? trackLength : (trackLength / valueRange); }, getRange: function() { return this.maxValue - this.minValue; }, reversePixelValue: function(pos) { return this.minValue + (pos / this.getRatio()); }, reversePercentageValue: function(pos) { return this.minValue + this.getRange() * (pos / 100); }, onDisable: function() { var me = this, i = 0, thumbs = me.thumbs, len = thumbs.length, thumb, el, xy; me.callParent(); for (; i < len; i++) { thumb = thumbs[i]; el = thumb.el; thumb.disable(); if (Ext.isIE) { xy = el.getXY(); el.hide(); me.innerEl.addCls(me.disabledCls).dom.disabled = true; if (!me.thumbHolder) { me.thumbHolder = me.endEl.createChild({ role: 'presentation', cls: Ext.baseCSSPrefix + 'slider-thumb ' + me.disabledCls }); } me.thumbHolder.show().setXY(xy); } } }, 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(); if (Ext.isIE) { me.innerEl.removeCls(me.disabledCls).dom.disabled = false; if (me.thumbHolder) { me.thumbHolder.hide(); } el.show(); me.syncThumbs(); } } }, syncThumbs: function() { if (this.rendered) { var thumbs = this.thumbs, length = thumbs.length, i = 0; for (; i < length; i++) { thumbs[i].move(this.calculateThumbPosition(thumbs[i].value)); } } }, getValue: function(index) { return Ext.isNumber(index) ? this.thumbs[index].value : this.getValues(); }, getValues: function() { var values = [], i = 0, thumbs = this.thumbs, len = thumbs.length; for (; i < len; i++) { values.push(thumbs[i].value); } return values; }, getSubmitValue: function() { var me = this; return (me.disabled || !me.submitValue) ? null : me.getValue(); }, reset: function() { var me = this, arr = [].concat(me.originalValue), a = 0, aLen = arr.length, val; for (; a < aLen; a++) { val = arr[a]; me.setValue(a, val); } me.clearInvalid(); delete me.wasValid; }, setReadOnly: function(readOnly) { var me = this, thumbs = me.thumbs, len = thumbs.length, i = 0; me.callParent(arguments); readOnly = me.readOnly; for (; i < len; ++i) { if (readOnly) { thumbs[i].disable(); } else { thumbs[i].enable(); } } }, beforeDestroy: function() { var me = this, thumbs = me.thumbs, t = 0, tLen = thumbs.length, thumb; if (me.rendered) { for (; t < tLen; t++) { thumb = thumbs[t]; Ext.destroy(thumb); } } me.callParent(); } }); 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' ], defaultBindProperty: 'value', initComponent: function() { if (this.publishOnComplete) { this.valuePublishEvent = 'changecomplete'; } this.callParent(); }, publishOnComplete: true, getValue: function() { return this.callParent([ 0 ]); }, setValue: function(value, animate) { var args = arguments, len = args.length; if (len === 1 || (len <= 3 && typeof args[1] !== 'number')) { args = Ext.toArray(args); args.unshift(0); } return this.callParent(args); }, getNearest: function() { return this.thumbs[0]; } }); Ext.define('Ext.slider.Widget', { extend: 'Ext.Widget', alias: 'widget.sliderwidget', requires: [ 'Ext.slider.Multi' ], cachedConfig: { vertical: false }, config: { clickToChange: true, ui: 'widget', value: 0, minValue: 0, maxValue: 100, publishOnComplete: true, twoWayBindable: { value: 1 } }, decimalPrecision: 0, defaultBindProperty: 'value', element: { reference: 'element', cls: Ext.baseCSSPrefix + 'slider', listeners: { mousedown: 'onMouseDown', dragstart: 'cancelDrag', drag: 'cancelDrag', dragend: 'cancelDrag' }, children: [ { reference: 'endEl', cls: Ext.baseCSSPrefix + 'slider-end', children: [ { reference: 'innerEl', cls: Ext.baseCSSPrefix + 'slider-inner' } ] } ] }, thumbCls: Ext.baseCSSPrefix + 'slider-thumb', horizontalProp: 'left', animateOnSetValue: undefined, applyValue: function(value) { var me = this, animate = me.animateOnSetValue, i, len; if (Ext.isArray(value)) { value = Ext.Array.from(value); for (i = 0 , len = value.length; i < len; ++i) { me.setThumbValue(i, value[i] = me.normalizeValue(value[i]), animate, true); } } else { value = me.normalizeValue(value); me.setThumbValue(0, value, animate, true); } return value; }, updateVertical: function(vertical, oldVertical) { this.element.removeCls(Ext.baseCSSPrefix + 'slider-' + (oldVertical ? 'vert' : 'horz')); this.element.addCls(Ext.baseCSSPrefix + 'slider-' + (vertical ? 'vert' : 'horz')); }, doSetHeight: function(height) { this.callParent(arguments); this.endEl.dom.style.height = this.innerEl.dom.style.height = '100%'; }, cancelDrag: function(e) { e.stopPropagation(); }, getThumb: function(ordinal) { var me = this, thumbConfig, result = (me.thumbs || (me.thumbs = []))[ordinal]; if (!result) { thumbConfig = { cls: me.thumbCls, style: {} }; thumbConfig['data-thumbIndex'] = ordinal; result = me.thumbs[ordinal] = me.innerEl.createChild(thumbConfig); } return result; }, getThumbPositionStyle: function() { return this.getVertical() ? 'bottom' : (this.rtl && Ext.rtl ? 'right' : 'left'); }, update: function() { var me = this, values = me.getValue(), len = values.length, i; for (i = 0; i < len; i++) { this.thumbs[i].dom.style[me.getThumbPositionStyle()] = me.calculateThumbPosition(values[i]) + '%'; } }, onMouseDown: function(e) { var me = this, thumb, trackPoint = e.getXY(), delta; if (!me.disabled && e.button === 0) { Ext.getDoc().on({ scope: me, capture: true, selectstart: me.stopSelect }); thumb = e.getTarget('.' + me.thumbCls, null, true); if (thumb) { me.animateOnSetValue = false; me.promoteThumb(thumb); me.captureMouse(me.onMouseMove, me.onMouseUp, [ thumb ], 1); delta = me.pointerOffset = thumb.getXY(); delta[0] += Math.floor(thumb.getWidth() / 2) - trackPoint[0]; delta[1] += Math.floor(thumb.getHeight() / 2) - trackPoint[1]; } else { if (me.getClickToChange()) { trackPoint = me.getTrackpoint(trackPoint); if (trackPoint != null) { me.onClickChange(trackPoint); } } } } }, onClickChange: function(trackPoint) { var me = this, thumb, index, value; thumb = me.getNearest(trackPoint); index = parseInt(thumb.getAttribute('data-thumbIndex'), 10); value = Ext.util.Format.round(me.reversePixelValue(trackPoint), me.decimalPrecision); if (index) { me.setThumbValue(index, value, undefined, true); } else { me.setValue(value); } }, getNearest: function(trackPoint) { var me = this, clickValue = me.reversePixelValue(trackPoint), nearestDistance = me.getRange() + 5, nearest = null, thumbs = me.thumbs, i = 0, len = thumbs.length, thumb, value, dist; for (; i < len; i++) { thumb = thumbs[i]; value = me.reversePercentageValue(parseInt(thumb.dom.style[me.getThumbPositionStyle()], 10)); dist = Math.abs(value - clickValue); if (Math.abs(dist) <= nearestDistance) { nearest = thumb; nearestDistance = dist; } } return nearest; }, promoteThumb: function(topThumb) { var thumbs = this.thumbStack || (this.thumbStack = Ext.Array.slice(this.thumbs)), ln = thumbs.length, zIndex = 10000, i; if (thumbs[0] !== topThumb) { Ext.Array.remove(thumbs, topThumb); thumbs.unshift(topThumb); } for (i = 0; i < ln; i++) { thumbs[i].el.setStyle('zIndex', zIndex); zIndex -= 1000; } }, doMouseMove: function(e, thumb, changeComplete) { var me = this, trackerXY = e.getXY(), newValue, thumbIndex, trackPoint; trackerXY[0] += me.pointerOffset[0]; trackerXY[1] += me.pointerOffset[1]; trackPoint = me.getTrackpoint(trackerXY); if (trackPoint) { newValue = me.reversePixelValue(trackPoint); thumbIndex = parseInt(thumb.getAttribute('data-thumbIndex'), 10); if (thumbIndex || (!changeComplete && me.getPublishOnComplete())) { me.setThumbValue(thumbIndex, newValue, false, changeComplete); } else { me.setValue(newValue); } } }, onMouseMove: function(e, thumb) { this.doMouseMove(e, thumb, false); }, onMouseUp: function(e, thumb) { var me = this; me.doMouseMove(e, thumb, true); Ext.getDoc().un({ scope: me, capture: true, selectstart: me.stopSelect }); delete me.animateOnSetValue; }, stopSelect: function(e) { e.stopEvent(); return false; }, setThumbValue: function(index, value, animate, changeComplete) { var me = this, thumb, thumbValue, len, i, values; if (Ext.isArray(index)) { values = index; animate = value; for (i = 0 , len = values.length; i < len; ++i) { me.setThumbValue(i, values[i], animate, changeComplete); } return me; } thumb = me.getThumb(index); thumbValue = me.reversePercentageValue(parseInt(thumb.dom.style[me.getThumbPositionStyle()], 10)); value = me.normalizeValue(value); if (value !== thumbValue && me.fireEvent('beforechange', me, value, thumbValue, thumb) !== false) { if (me.element.dom) { me.element.set({ 'aria-valuenow': value, 'aria-valuetext': value }); me.moveThumb(thumb, me.calculateThumbPosition(value), Ext.isDefined(animate) ? animate !== false : me.animate); me.fireEvent('change', me, value, thumb); } } return me; }, getValue: function(index) { var me = this, value; if (Ext.isNumber(index)) { value = me.thumbs[index].dom.style[me.getThumbPositionStyle()]; value = me.reversePercentageValue(parseInt(value, 10)); } else { value = me.getValues(); if (value.length === 1) { value = value[0]; } } return value; }, getValues: function() { var me = this, values = [], i = 0, thumbs = me.thumbs, len = thumbs.length; for (; i < len; i++) { values.push(me.reversePercentageValue(parseInt(me.thumbs[i].dom.style[me.getThumbPositionStyle()], 10))); } return values; }, moveThumb: function(thumb, v, animate) { var me = this, styleProp = me.getThumbPositionStyle(), to, from; v += '%'; if (!animate) { thumb.dom.style[styleProp] = v; } else { to = {}; to[styleProp] = v; if (!Ext.supports.GetPositionPercentage) { from = {}; from[styleProp] = thumb.dom.style[styleProp]; } new Ext.fx.Anim({ target: thumb, duration: 350, from: from, to: to }); } }, normalizeValue: function(v) { var me = this, snapFn = me.zeroBasedSnapping ? 'snap' : 'snapInRange'; v = Ext.Number[snapFn](v, me.increment, me.minValue, me.maxValue); v = Ext.util.Format.round(v, me.decimalPrecision); v = Ext.Number.constrain(v, me.minValue, me.maxValue); return v; }, getTrackpoint: function(xy) { var me = this, vertical = me.getVertical(), sliderTrack = me.innerEl, trackLength, result, positionProperty; if (vertical) { positionProperty = 'top'; trackLength = sliderTrack.getHeight(); } else { positionProperty = 'left'; trackLength = sliderTrack.getWidth(); } xy = me.transformTrackPoints(sliderTrack.translatePoints(xy)); result = Ext.Number.constrain(xy[positionProperty], 0, trackLength); return vertical ? trackLength - result : result; }, transformTrackPoints: Ext.identityFn, calculateThumbPosition: function(v) { var me = this, pos = (v - me.getMinValue()) / me.getRange() * 100; if (isNaN(pos)) { pos = 0; } return pos; }, getRatio: function() { var me = this, innerEl = me.innerEl, trackLength = me.getVertical() ? innerEl.getHeight() : innerEl.getWidth(), valueRange = me.getRange(); return valueRange === 0 ? trackLength : (trackLength / valueRange); }, getRange: function() { return this.getMaxValue() - this.getMinValue(); }, reversePixelValue: function(pos) { return this.getMinValue() + (pos / this.getRatio()); }, reversePercentageValue: function(pos) { return this.getMinValue() + this.getRange() * (pos / 100); }, captureMouse: function(onMouseMove, onMouseUp, args, appendArgs) { var me = this, onMouseupWrap, listeners; onMouseMove = onMouseMove && Ext.Function.bind(onMouseMove, me, args, appendArgs); onMouseUp = onMouseUp && Ext.Function.bind(onMouseUp, me, args, appendArgs); onMouseupWrap = function() { Ext.getDoc().un(listeners); if (onMouseUp) { onMouseUp.apply(me, arguments); } }; listeners = { mousemove: onMouseMove, mouseup: onMouseupWrap }; Ext.getDoc().on(listeners); } }); Ext.define('Ext.sparkline.Shape', { constructor: function(target, id, type, args) { this.target = target; this.id = id; this.type = type; this.args = args; }, append: function() { this.target.appendShape(this); return this; } }); Ext.define('Ext.sparkline.CanvasBase', { requires: [ 'Ext.sparkline.Shape' ], shapeCount: 0, _pxregex: /(\d+)(px)?\s*$/i, constructor: function(ownerSparkLine) { this.owner = ownerSparkLine; }, setWidth: function(width) { this.pixelWidth = width; }, setHeight: function(height) { this.pixelHeight = height; }, drawLine: function(x1, y1, x2, y2, lineColor, lineWidth) { return this.drawShape([ [ x1, y1 ], [ x2, y2 ] ], lineColor, lineWidth); }, drawShape: function(path, lineColor, fillColor, lineWidth) { return this._genShape('Shape', [ path, lineColor, fillColor, lineWidth ]); }, drawCircle: function(x, y, radius, lineColor, fillColor, lineWidth) { return this._genShape('Circle', [ x, y, radius, lineColor, fillColor, lineWidth ]); }, drawPieSlice: function(x, y, radius, startAngle, endAngle, lineColor, fillColor) { return this._genShape('PieSlice', [ x, y, radius, startAngle, endAngle, lineColor, fillColor ]); }, drawRect: function(x, y, width, height, lineColor, fillColor) { return this._genShape('Rect', [ x, y, width, height, lineColor, fillColor ]); }, getElement: function() { return this.el; }, getLastShapeId: function() { return this.lastShapeId; }, reset: function() { Ext.Error.raise('reset not implemented'); }, _genShape: function(shapetype, shapeargs) { var id = this.shapeCount++; shapeargs.unshift(id); return new Ext.sparkline.Shape(this, id, shapetype, shapeargs); }, appendShape: function(shape) { Ext.Error.raise('appendShape not implemented'); }, replaceWithShape: function(shapeid, shape) { Ext.Error.raise('replaceWithShape not implemented'); }, insertAfterShape: function(shapeid, shape) { Ext.Error.raise('insertAfterShape not implemented'); }, removeShapeId: function(shapeid) { Ext.Error.raise('removeShapeId not implemented'); }, getShapeAt: function(x, y) { Ext.Error.raise('getShapeAt not implemented'); }, render: function() { Ext.Error.raise('render not implemented'); } }); Ext.define('Ext.sparkline.CanvasCanvas', { extend: 'Ext.sparkline.CanvasBase', statics: { contextOverrides: (function() { var ratio = window.devicePixelRatio || 1; return { moveTo: function(x, y) { this.$moveTo(x * ratio, y * ratio); }, lineTo: function(x, y) { this.$lineTo(x * ratio, y * ratio); }, arc: function(x, y, radius, startAngle, endAngle, counterclockwise) { this.$arc(x * ratio, y * ratio, radius * ratio, startAngle, endAngle, counterclockwise); }, clearRect: function(x, y, width, height) { this.$clearRect(x * ratio, y * ratio, width * ratio, height * ratio); } }; })() }, setWidth: function(width) { this.callParent(arguments); this.owner.element.dom.width = width * (window.devicePixelRatio || 1); }, setHeight: function(height) { this.callParent(arguments); this.owner.element.dom.height = height * (window.devicePixelRatio || 1); }, onOwnerUpdate: function() { var me = this; me.el = me.owner.element; me.interact = !me.owner.initialConfig.disableInteraction; me.shapes = {}; me.shapeseq = []; me.currentTargetShapeId = me.lastShapeId = null; }, _getContext: function(lineColor, fillColor, lineWidth) { var context = this.el.dom.getContext('2d'), overrides = Ext.sparkline.CanvasCanvas.contextOverrides, name; if (!this.context) { for (name in overrides) { context['$' + name] = context[name]; } Ext.apply(context, overrides); this.context = context; } if (lineColor != null) { context.strokeStyle = lineColor; } context.lineWidth = lineWidth || 1; if (fillColor != null) { context.fillStyle = fillColor; } return context; }, reset: function() { var context = this._getContext(); context.clearRect(0, 0, this.pixelWidth, this.pixelHeight); this.shapes = {}; this.shapeseq = []; this.currentTargetShapeId = this.lastShapeId = null; }, _drawShape: function(shapeid, path, lineColor, fillColor, lineWidth) { var context = this._getContext(lineColor, fillColor, lineWidth), i, plen; context.beginPath(); context.moveTo(path[0][0] + 0.5, path[0][1] + 0.5); for (i = 1 , plen = path.length; i < plen; i++) { context.lineTo(path[i][0] + 0.5, path[i][1] + 0.5); } if (lineColor != null) { context.stroke(); } if (fillColor != null) { context.fill(); } if (this.targetX != null && this.targetY != null && context.isPointInPath(this.targetX, this.targetY)) { this.currentTargetShapeId = shapeid; } }, _drawCircle: function(shapeid, x, y, radius, lineColor, fillColor, lineWidth) { var context = this._getContext(lineColor, fillColor, lineWidth); context.beginPath(); context.arc(x, y, radius, 0, 2 * Math.PI, false); if (this.targetX != null && this.targetY != null && context.isPointInPath(this.targetX, this.targetY)) { this.currentTargetShapeId = shapeid; } if (lineColor !== undefined) { context.stroke(); } if (fillColor !== undefined) { context.fill(); } }, _drawPieSlice: function(shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) { var context = this._getContext(lineColor, fillColor); context.beginPath(); context.moveTo(x, y); context.arc(x, y, radius, startAngle, endAngle, false); context.lineTo(x, y); context.closePath(); if (lineColor != null) { context.stroke(); } if (fillColor) { context.fill(); } if (this.targetX !== undefined && this.targetY !== undefined && context.isPointInPath(this.targetX, this.targetY)) { this.currentTargetShapeId = shapeid; } }, _drawRect: function(shapeid, x, y, width, height, lineColor, fillColor) { return this._drawShape(shapeid, [ [ x, y ], [ x + width, y ], [ x + width, y + height ], [ x, y + height ], [ x, y ] ], lineColor, fillColor); }, appendShape: function(shape) { this.shapes[shape.id] = shape; this.shapeseq.push(shape.id); this.lastShapeId = shape.id; return shape.id; }, replaceWithShape: function(shapeid, shape) { var shapeseq = this.shapeseq, i; this.shapes[shape.id] = shape; for (i = shapeseq.length; i--; ) { if (shapeseq[i] == shapeid) { shapeseq[i] = shape.id; } } delete this.shapes[shapeid]; }, replaceWithShapes: function(shapeids, shapes) { var shapeseq = this.shapeseq, shapemap = {}, sid, i, first; for (i = shapeids.length; i--; ) { shapemap[shapeids[i]] = true; } for (i = shapeseq.length; i--; ) { sid = shapeseq[i]; if (shapemap[sid]) { shapeseq.splice(i, 1); delete this.shapes[sid]; first = i; } } for (i = shapes.length; i--; ) { shapeseq.splice(first, 0, shapes[i].id); this.shapes[shapes[i].id] = shapes[i]; } }, insertAfterShape: function(shapeid, shape) { var shapeseq = this.shapeseq, i; for (i = shapeseq.length; i--; ) { if (shapeseq[i] === shapeid) { shapeseq.splice(i + 1, 0, shape.id); this.shapes[shape.id] = shape; return; } } }, removeShapeId: function(shapeid) { var shapeseq = this.shapeseq, i; for (i = shapeseq.length; i--; ) { if (shapeseq[i] === shapeid) { shapeseq.splice(i, 1); break; } } delete this.shapes[shapeid]; }, getShapeAt: function(x, y) { this.targetX = x; this.targetY = y; this.render(); return this.currentTargetShapeId; }, render: function() { var shapeseq = this.shapeseq, shapes = this.shapes, shapeCount = shapeseq.length, context = this._getContext(), shapeid, shape, i; context.clearRect(0, 0, this.pixelWidth, this.pixelHeight); for (i = 0; i < shapeCount; i++) { shapeid = shapeseq[i]; shape = shapes[shapeid]; this['_draw' + shape.type].apply(this, shape.args); } if (!this.interact) { this.shapes = {}; this.shapeseq = []; } } }); Ext.define('Ext.sparkline.VmlCanvas', { extend: 'Ext.sparkline.CanvasBase', setWidth: function(width) { var me = this; me.callParent(arguments); me.owner.groupEl.dom.coordsize = me.width + ' ' + (me.height || 0); me.owner.groupEl.dom.style.width = width + 'px'; }, setHeight: function(height) { var me = this; me.callParent(arguments); me.owner.groupEl.dom.coordsize = (me.width || 0) + ' ' + me.height; me.owner.groupEl.dom.style.height = height + 'px'; }, onOwnerUpdate: function() { var me = this; me.group = me.owner.groupEl; me.el = me.owner.element; me.prerender = []; }, _drawShape: function(shapeid, path, lineColor, fillColor, lineWidth) { var vpath = [], initial, stroke, fill, closed, plen, i; for (i = 0 , plen = path.length; i < plen; i++) { vpath[i] = (path[i][0]) + ',' + (path[i][1]); } initial = vpath.splice(0, 1); lineWidth = lineWidth == null ? 1 : lineWidth; stroke = lineColor == null ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" '; fill = fillColor == null ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : ''; return [ '' ].join(''); }, _drawCircle: function(shapeid, x, y, radius, lineColor, fillColor, lineWidth) { var circumference = radius * 2, stroke, fill; x -= radius; y -= radius; stroke = lineColor == null ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" '; fill = fillColor == null ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; return [ '' ].join(''); }, _drawPieSlice: function(shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) { var vpath, width = this.pixelWidth, height = this.pixelHeight, startx, starty, endx, endy, stroke = lineColor == null ? ' stroked="false" ' : ' strokeWeight="1px" strokeColor="' + lineColor + '" ', fill = fillColor == null ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; if (startAngle === endAngle) { return ''; } if ((endAngle - startAngle) === (2 * Math.PI)) { startAngle = 0; endAngle = (2 * Math.PI); } startx = x + Math.round(Math.cos(startAngle) * radius); starty = y + Math.round(Math.sin(startAngle) * radius); endx = x + Math.round(Math.cos(endAngle) * radius); endy = y + Math.round(Math.sin(endAngle) * radius); if (startx === endx && starty === endy) { if ((endAngle - startAngle) < Math.PI) { return ''; } startx = endx = x + radius; starty = endy = y; } if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) { return ''; } vpath = [ x - radius, y - radius, x + radius, y + radius, startx, starty, endx, endy ]; return [ '' ].join(''); }, _drawRect: function(shapeid, x, y, width, height, lineColor, fillColor) { return this._drawShape(shapeid, [ [ x, y ], [ x, y + height ], [ x + width, y + height ], [ x + width, y ], [ x, y ] ], lineColor, fillColor); }, reset: function() { Ext.fly(this.group).empty(); }, appendShape: function(shape) { this.prerender.push(this['_draw' + shape.type].apply(this, shape.args)); this.lastShapeId = shape.id; return shape.id; }, replaceWithShape: function(shapeid, shape) { var existing = this.el.getById('jqsshape' + shapeid, true), vel = this['_draw' + shape.type].apply(this, shape.args); existing.outerHTML = vel; }, replaceWithShapes: function(shapeids, shapes) { var existing = this.el.getById('jqsshape' + shapeids[0], true), replace = '', slen = shapes.length, i; for (i = 0; i < slen; i++) { replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args); } existing.outerHTML = replace; for (i = 1; i < shapeids.length; i++) { this.el.getById('jqsshape' + shapeids[i]).destroy(); } }, insertAfterShape: function(shapeid, shape) { var existing = this.el.getById('jqsshape' + shapeid, true), vel = this['_draw' + shape.type].apply(this, shape.args); existing.insertAdjacentHTML('afterEnd', vel); }, removeShapeId: function(shapeid) { var existing = this.el.getById('jqsshape' + shapeid, true); this.group.removeChild(existing); }, getShapeAt: function(x, y) { var shapeid = this.el.id.substr(8); return shapeid; }, render: function() { this.group.dom.innerHTML = this.prerender.join(''); } }, function() { Ext.onInternalReady(function() { var doc = document; if (doc.namespaces && !doc.namespaces.svml) { doc.namespaces.add("svml", "urn:schemas-microsoft-com:vml", '#default#VML'); } }); }); Ext.define('Ext.sparkline.Base', { extend: 'Ext.Widget', requires: [ 'Ext.XTemplate', 'Ext.sparkline.CanvasCanvas', 'Ext.sparkline.VmlCanvas' ], cachedConfig: { baseCls: Ext.baseCSSPrefix + 'sparkline', lineColor: '#157fcc', fillColor: '#def', defaultPixelsPerValue: 3, tagValuesAttribute: 'values', enableTagOptions: false, enableHighlight: true, highlightColor: null, highlightLighten: 1.4, tooltipSkipNull: true, tooltipPrefix: '', tooltipSuffix: '', disableTooltips: false, disableInteraction: false, tipTpl: null }, config: { values: null }, element: { tag: 'canvas', reference: 'element', style: { display: 'inline-block', verticalAlign: 'top' }, listeners: { mouseenter: 'onMouseEnter', mouseleave: 'onMouseLeave', mousemove: 'onMouseMove' }, width: 0, height: 0 }, defaultBindProperty: 'values', redrawQueue: {}, inheritableStatics: { sparkLineTipClass: Ext.baseCSSPrefix + 'sparkline-tip-target', onClassCreated: function(cls) { var proto = cls.prototype, configs = cls.getConfigurator().configs, config; for (config in configs) { if (config !== 'tipTpl') { proto[Ext.Config.get(config).names.apply] = proto.applyConfigChange; } } } }, constructor: function(config) { var me = this; me.canvas = Ext.supports.Canvas ? new Ext.sparkline.CanvasCanvas(me) : new Ext.sparkline.VmlCanvas(me); if (!me.getDisableTooltips()) { me.element.cls = Ext.sparkline.Base.sparkLineTipClass; } Ext.apply(me, config); me.callParent([ config ]); me.el = me.element; }, all: function(val, arr, ignoreNull) { var i; for (i = arr.length; i--; ) { if (ignoreNull && arr[i] === null) { continue; } if (arr[i] !== val) { return false; } } return true; }, applyConfigChange: function(newValue) { var me = this; me.redrawQueue[me.getId()] = me; if (!me.redrawTimer) { Ext.sparkline.Base.prototype.redrawTimer = Ext.Function.requestAnimationFrame(me.processRedrawQueue); } return newValue; }, applyTipTpl: function(tipTpl) { if (!tipTpl.isTemplate) { tipTpl = new Ext.XTemplate(tipTpl); } return tipTpl; }, normalizeValue: function(val) { var nf; switch (val) { case 'undefined': val = undefined; break; case 'null': val = null; break; case 'true': val = true; break; case 'false': val = false; break; default: nf = parseFloat(val); if (val == nf) { val = nf; }; } return val; }, normalizeValues: function(vals) { var i, result = []; for (i = vals.length; i--; ) { result[i] = this.normalizeValue(vals[i]); } return result; }, doSetWidth: function(width) { var me = this, dom = me.element.dom; me.callParent(arguments); me.canvas.setWidth(width); me.width = width; if (me.height == null) { me.setHeight(parseInt(me.measurer.getCachedStyle(dom.parentNode, 'line-height'), 10)); } else { me.redrawQueue[me.getId()] = me; } }, doSetHeight: function(height) { var me = this; me.callParent(arguments); me.canvas.setHeight(height); me.height = height; me.redrawQueue[me.getId()] = me; }, updateValues: function(values) { this.values = values; }, redraw: function() { var me = this, tooltip; if (me.getValues()) { tooltip = me.tooltip; if (tooltip && tooltip.isVisible() && me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) { me.tooltip.triggerElement = me.el.dom; } me.onUpdate(); me.canvas.onOwnerUpdate(); me.renderGraph(); } }, onUpdate: Ext.emptyFn, renderGraph: function() { var ret = true; if (this.disabled) { this.canvas.reset(); ret = false; } return ret; }, onMouseEnter: function(e) { this.onMouseMove(e); }, onMouseMove: function(e) { this.currentPageXY = e.getPoint(); this.redraw(); }, onMouseLeave: function() { var me = this; me.currentPageXY = me.targetX = me.targetY = null; me.redraw(); }, updateDisplay: function() { var me = this, offset, tooltip, tooltipHTML, region; if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) { offset = me.canvas.el.getXY(); region = me.getRegion(me.currentPageXY[0] - offset[0], me.currentPageXY[1] - offset[1]); if (region != null && !me.disableHighlight) { me.renderHighlight(region); } me.fireEvent('sparklineregionchange', me); tooltip = me.tooltip; if (region != null && tooltip) { tooltipHTML = me.getRegionTooltip(region); if (tooltipHTML) { if (!me.lastTooltipHTML || tooltipHTML[0] !== me.lastTooltipHTML[0] || tooltipHTML[1] !== me.lastTooltipHTML[1]) { tooltip.setTitle(tooltipHTML[0]); tooltip.update(tooltipHTML[1]); me.lastTooltipHTML = tooltipHTML; } } else { tooltip.hide(); } } } }, getRegion: Ext.emptyFn, getRegionTooltip: function(region) { var me = this, header = me.tooltipChartTitle, entries = [], tipTpl = me.getTipTpl(), fields, showFields, showFieldsKey, newFields, fv, formatter, fieldlen, i, j; fields = me.getRegionFields(region); formatter = me.tooltipFormatter; if (formatter) { return formatter(me, me, fields); } if (!tipTpl) { return ''; } if (!Ext.isArray(fields)) { fields = [ fields ]; } showFields = me.tooltipFormatFieldlist; showFieldsKey = me.tooltipFormatFieldlistKey; if (showFields && showFieldsKey) { newFields = []; for (i = fields.length; i--; ) { fv = fields[i][showFieldsKey]; if ((j = Ext.Array.indexOf(fv, showFields)) !== -1) { newFields[j] = fields[i]; } } fields = newFields; } fieldlen = fields.length; for (j = 0; j < fieldlen; j++) { if (!fields[j].isNull || !me.getTooltipSkipNull()) { Ext.apply(fields[j], { prefix: me.getTooltipPrefix(), suffix: me.getTooltipSuffix() }); entries.push(tipTpl.apply(fields[j])); } } if (header || entries.length) { return [ header, entries.join('
    ') ]; } return ''; }, getRegionFields: Ext.emptyFn, calcHighlightColor: function(color) { var me = this, highlightColor = me.getHighlightColor(), lighten = me.getHighlightLighten(), parse, mult, rgbnew, i; if (highlightColor) { return highlightColor; } if (lighten) { parse = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color) || /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color); if (parse) { rgbnew = []; mult = color.length === 4 ? 16 : 1; for (i = 0; i < 3; i++) { rgbnew[i] = Ext.Number.constrain(Math.round(parseInt(parse[i + 1], 16) * mult * lighten), 0, 255); } return 'rgb(' + rgbnew.join(',') + ')'; } } return color; }, destroy: function() { delete this.redrawQueue[this.getId()]; this.callParent(); } }, function(SparklineBase) { var proto = SparklineBase.prototype; Ext.onInternalReady(function() { proto.tooltip = new Ext.tip.ToolTip({ id: 'sparklines-tooltip', target: document.body, delegate: '.' + SparklineBase.sparkLineTipClass, showDelay: 0, dismissDelay: 0, hideDelay: 400 }); }); SparklineBase.onClassCreated(SparklineBase); proto.processRedrawQueue = function() { var redrawQueue = proto.redrawQueue, id; for (id in redrawQueue) { redrawQueue[id].redraw(); } proto.redrawQueue = {}; proto.redrawTimer = 0; }; if (!Ext.supports.Canvas) { SparklineBase.prototype.element = { tag: 'span', reference: 'element', listeners: { mouseenter: 'onMouseEnter', mouseleave: 'onMouseLeave', mousemove: 'onMouseMove' }, style: { display: 'inline-block', position: 'relative', overflow: 'hidden', margin: '0px', padding: '0px', verticalAlign: 'top', cursor: 'default' }, children: [ { tag: 'svml:group', reference: 'groupEl', coordorigin: '0 0', coordsize: '0 0', style: 'position:absolute;width:0;height:0;pointer-events:none' } ] }; } }); Ext.define('Ext.sparkline.BarBase', { extend: 'Ext.sparkline.Base', renderHighlight: function(region) { this.renderRegion(region, true); }, renderGraph: function() { var me = this, values = me.values, canvas = me.canvas, regionShapes = me.regionShapes || (me.regionShapes = {}), shapes, ids, i, j; if (!me.callParent()) { return; } for (i = values.length; i--; ) { shapes = me.renderRegion(i); if (shapes) { if (Ext.isArray(shapes)) { ids = []; for (j = shapes.length; j--; ) { shapes[j].append(); ids.push(shapes[j].id); } regionShapes[i] = ids; } else { shapes.append(); regionShapes[i] = shapes.id; } } else { regionShapes[i] = null; } } if (me.currentPageXY) { me.currentRegion = null; me.updateDisplay(); } canvas.render(); } }); Ext.define('Ext.sparkline.RangeMap', { constructor: function(map) { var key, range, rangelist = []; for (key in map) { if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) { range = key.split(':'); range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]); range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]); range[2] = map[key]; rangelist.push(range); } } this.map = map; this.rangelist = rangelist || false; }, get: function(value) { var rangelist = this.rangelist, i, range, result; if ((result = this.map[value]) !== undefined) { return result; } if (rangelist) { for (i = rangelist.length; i--; ) { range = rangelist[i]; if (range[0] <= value && range[1] >= value) { return range[2]; } } } } }); Ext.define('Ext.sparkline.Bar', { extend: 'Ext.sparkline.BarBase', requires: [ 'Ext.sparkline.RangeMap' ], alias: 'widget.sparklinebar', config: { barColor: '#3366cc', negBarColor: '#f44', stackedBarColor: [ '#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00', '#dd4477', '#0099c6', '#990099' ], zeroColor: null, nullColor: null, zeroAxis: true, barWidth: 4, barSpacing: 1, chartRangeMin: null, chartRangeMax: null, chartRangeClip: false, colorMap: null, tipTpl: new Ext.XTemplate('● {prefix}{value}{suffix}') }, remove: function(vals, filter) { var i, vl, result = []; for (i = 0 , vl = vals.length; i < vl; i++) { if (vals[i] !== filter) { result.push(vals[i]); } } return result; }, all: function(arr, val, ignoreNull) { var i; for (i = arr.length; i--; ) { if (ignoreNull && arr[i] === null) { continue; } if (arr[i] !== val) { return false; } } return true; }, applyColorMap: function(colorMap) { var me = this; if (Ext.isArray(colorMap)) { me.colorMapByIndex = colorMap; me.colorMapByValue = null; } else { me.colorMapByIndex = null; me.colorMapByValue = colorMap; if (me.colorMapByValue && me.colorMapByValue.get == null) { me.colorMapByValue = new Ext.sparkline.RangeMap(colorMap); } } return colorMap; }, onUpdate: function() { var me = this, values = me.values, barWidth = me.getBarWidth(), barSpacing = me.getBarSpacing(), chartRangeMin = me.getChartRangeMin(), chartRangeMax = me.getChartRangeMax(), chartRangeClip = me.getChartRangeClip(), stackMin = Infinity, stackMax = -Infinity, isStackString, groupMin, groupMax, stackRanges, numValues, i, vlen, range, zeroAxis = me.getZeroAxis(), xAxisOffset, min, max, clipMin, clipMax, stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, stackTotals = [], stackRangesNeg = []; for (i = 0 , vlen = values.length; i < vlen; i++) { val = values[i]; isStackString = typeof (val) === 'string' && val.indexOf(':') > -1; if (isStackString || Ext.isArray(val)) { stacked = true; if (isStackString) { val = values[i] = me.normalizeValues(val.split(':')); } val = me.remove(val, null); groupMin = Math.min.apply(Math, val); groupMax = Math.max.apply(Math, val); if (groupMin < stackMin) { stackMin = groupMin; } if (groupMax > stackMax) { stackMax = groupMax; } } } me.stacked = stacked; me.regionShapes = {}; me.totalBarWidth = barWidth + barSpacing; me.width = (values.length * barWidth) + ((values.length - 1) * barSpacing); if (chartRangeClip) { clipMin = chartRangeMin == null ? -Infinity : chartRangeMin; clipMax = chartRangeMax == null ? Infinity : chartRangeMax; } numValues = []; stackRanges = stacked ? [] : numValues; for (i = 0 , vlen = values.length; i < vlen; i++) { if (stacked) { vlist = values[i]; values[i] = svals = []; stackTotals[i] = 0; stackRanges[i] = stackRangesNeg[i] = 0; for (j = 0 , slen = vlist.length; j < slen; j++) { val = svals[j] = chartRangeClip ? Ext.Number.constrain(vlist[j], clipMin, clipMax) : vlist[j]; if (val !== null) { if (val > 0) { stackTotals[i] += val; } if (stackMin < 0 && stackMax > 0) { if (val < 0) { stackRangesNeg[i] += Math.abs(val); } else { stackRanges[i] += val; } } else { stackRanges[i] += Math.abs(val - (val < 0 ? stackMax : stackMin)); } numValues.push(val); } } } else { val = chartRangeClip ? Ext.Number.constrain(values[i], clipMin, clipMax) : values[i]; val = values[i] = me.normalizeValue(val); if (val !== null) { numValues.push(val); } } } me.max = max = Math.max.apply(Math, numValues); me.min = min = Math.min.apply(Math, numValues); me.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max; me.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min; if (chartRangeMin != null && (chartRangeClip || chartRangeMin < min)) { min = chartRangeMin; } if (chartRangeMax != null && (chartRangeClip || chartRangeMax > max)) { max = chartRangeMax; } if (min <= 0 && max >= 0 && zeroAxis) { xAxisOffset = 0; } else if (!zeroAxis) { xAxisOffset = min; } else if (min > 0) { xAxisOffset = min; } else { xAxisOffset = max; } me.xAxisOffset = xAxisOffset; range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - min; me.canvasHeightEf = (zeroAxis && min < 0) ? me.getHeight() - 2 : me.getHeight() - 1; if (min < xAxisOffset) { yMaxCalc = (stacked && max >= 0) ? stackMax : max; yoffset = (yMaxCalc - xAxisOffset) / range * me.getHeight(); if (yoffset !== Math.ceil(yoffset)) { me.canvasHeightEf -= 2; yoffset = Math.ceil(yoffset); } } else { yoffset = me.getHeight(); } me.yoffset = yoffset; me.range = range; }, getRegion: function(x, y) { var result = Math.floor(x / this.totalBarWidth); return (result < 0 || result >= this.values.length) ? undefined : result; }, getRegionFields: function(region) { var values = Ext.Array.from(this.values[region]), result = [], value, i; for (i = values.length; i--; ) { value = values[i]; result.push({ isNull: value === null, value: value, color: this.calcColor(i, value, region), offset: region }); } return result; }, calcColor: function(stacknum, value, valuenum) { var me = this, colorMapByIndex = me.colorMapByIndex, colorMapByValue = me.colorMapByValue, color, newColor, zeroColor = me.getZeroColor(); if (this.stacked) { color = me.getStackedBarColor(); } else { color = (value < 0) ? me.getNegBarColor() : me.getBarColor(); } if (value === 0 && zeroColor !== undefined) { color = zeroColor; } if (colorMapByValue && (newColor = colorMapByValue.get(value))) { color = newColor; } else if (colorMapByIndex && colorMapByIndex.length > valuenum) { color = colorMapByIndex[valuenum]; } return Ext.isArray(color) ? color[stacknum % color.length] : color; }, renderRegion: function(valuenum, highlight) { var me = this, vals = me.values[valuenum], xaxisOffset = me.xAxisOffset, range = me.range, stacked = me.stacked, canvas = me.canvas, barWidth = me.getBarWidth(), x = valuenum * me.totalBarWidth, canvasHeightEf = me.canvasHeightEf, yoffset = me.yoffset, y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin, nullColor = me.getNullColor(); vals = Ext.isArray(vals) ? vals : [ vals ]; valcount = vals.length; val = vals[0]; isNull = me.all(vals, null); allMin = me.all(vals, xaxisOffset, true); if (isNull) { if (nullColor) { color = highlight ? nullColor : me.calcHighlightColor(nullColor, me); y = (yoffset > 0) ? yoffset - 1 : yoffset; canvas.drawRect(x, y, barWidth - 1, 0, color, color).append(); } return; } yoffsetNeg = yoffset; for (i = 0; i < valcount; i++) { val = vals[i]; if (stacked && val === xaxisOffset) { if (!allMin || minPlotted) { continue; } minPlotted = true; } if (range > 0) { height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range))) + 1; } else { height = 1; } if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) { y = yoffsetNeg; yoffsetNeg += height; } else { y = yoffset - height; yoffset -= height; } color = me.calcColor(i, val, valuenum); if (highlight) { color = me.calcHighlightColor(color, me); } canvas.drawRect(x, y, barWidth - 1, height - 1, color, color).append(); } } }, function(cls) { cls.onClassCreated(cls); }); Ext.define('Ext.sparkline.Box', { extend: 'Ext.sparkline.Base', alias: 'widget.sparklinebox', config: { raw: false, boxLineColor: '#000', boxFillColor: '#cdf', whiskerColor: '#000', outlierLineColor: '#333', outlierFillColor: '#fff', medianColor: '#f00', showOutliers: true, outlierIQR: 1.5, spotRadius: 1.5, target: null, targetColor: '#4a2', chartRangeMin: null, chartRangeMax: null, tipTpl: new Ext.XTemplate('{field:this.fields}: {value}', { fields: function(v) { var fields = { lq: 'Lower Quartile', med: 'Median', uq: 'Upper Quartile', lo: 'Left Outlier', ro: 'Right Outlier', lw: 'Left Whisker', rw: 'Right Whisker' }; return fields[v]; } }), tooltipFormatFieldlistKey: 'field' }, quartile: function(values, q) { var vl; if (q === 2) { vl = Math.floor(values.length / 2); return values.length % 2 ? values[vl] : (values[vl - 1] + values[vl]) / 2; } else { if (values.length % 2) { vl = (values.length * q + q) / 4; return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl - 1]; } else { vl = (values.length * q + 2) / 4; return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl - 1]; } } }, applyValues: function(newValues) { newValues = Ext.Array.map(Ext.Array.from(newValues), Number); this.disabled = !(newValues && newValues.length); return newValues; }, getRegion: function() { return 1; }, getRegionFields: function() { var result = [ { field: 'lq', value: this.quartiles[0] }, { field: 'med', value: this.quartiles[1] }, { field: 'uq', value: this.quartiles[2] } ]; if (this.loutlier !== undefined) { result.push({ field: 'lo', value: this.loutlier }); } if (this.routlier !== undefined) { result.push({ field: 'ro', value: this.routlier }); } if (this.lwhisker !== undefined) { result.push({ field: 'lw', value: this.lwhisker }); } if (this.rwhisker !== undefined) { result.push({ field: 'rw', value: this.rwhisker }); } return result; }, renderHighlight: Ext.emptyFn, renderGraph: function() { var me = this, canvas = me.canvas, values = me.values, vlen = values.length, canvasWidth = me.getWidth(), canvasHeight = me.getHeight(), chartRangeMin = me.getChartRangeMin(), chartRangeMax = me.getChartRangeMax(), minValue = chartRangeMin == null ? Math.min.apply(Math, values) : chartRangeMin, maxValue = chartRangeMax == null ? Math.max.apply(Math, values) : chartRangeMax, canvasLeft = 0, lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i, size, unitSize, spotRadius = me.getSpotRadius(), outlierLineColor = me.getOutlierLineColor(), outlierFillColor = me.getOutlierFillColor(), showOutliers = me.getShowOutliers(), outlierIQR = me.getOutlierIQR(), lineColor = me.getLineColor(), whiskerColor = me.getWhiskerColor(), targetColor = me.getTargetColor(); if (!me.callParent()) { return; } if (me.raw) { if (showOutliers && values.length > 5) { loutlier = values[0]; lwhisker = values[1]; q1 = values[2]; q2 = values[3]; q3 = values[4]; rwhisker = values[5]; routlier = values[6]; } else { lwhisker = values[0]; q1 = values[1]; q2 = values[2]; q3 = values[3]; rwhisker = values[4]; } } else { values.sort(function(a, b) { return a - b; }); q1 = me.quartile(values, 1); q2 = me.quartile(values, 2); q3 = me.quartile(values, 3); iqr = q3 - q1; if (showOutliers) { lwhisker = rwhisker = null; for (i = 0; i < vlen; i++) { if (lwhisker == null && values[i] > q1 - (iqr * outlierIQR)) { lwhisker = values[i]; } if (values[i] < q3 + (iqr * outlierIQR)) { rwhisker = values[i]; } } loutlier = values[0]; routlier = values[vlen - 1]; } else { lwhisker = values[0]; rwhisker = values[vlen - 1]; } } me.quartiles = [ q1, q2, q3 ]; me.lwhisker = lwhisker; me.rwhisker = rwhisker; me.loutlier = loutlier; me.routlier = routlier; unitSize = canvasWidth / (maxValue - minValue + 1); if (showOutliers) { canvasLeft = Math.ceil(spotRadius); canvasWidth -= 2 * Math.ceil(spotRadius); unitSize = canvasWidth / (maxValue - minValue + 1); if (loutlier < lwhisker) { canvas.drawCircle((loutlier - minValue) * unitSize + canvasLeft, canvasHeight / 2, spotRadius, outlierLineColor, outlierFillColor).append(); } if (routlier > rwhisker) { canvas.drawCircle((routlier - minValue) * unitSize + canvasLeft, canvasHeight / 2, spotRadius, outlierLineColor, outlierFillColor).append(); } } canvas.drawRect(Math.round((q1 - minValue) * unitSize + canvasLeft), Math.round(canvasHeight * 0.1), Math.round((q3 - q1) * unitSize), Math.round(canvasHeight * 0.8), me.getBoxLineColor(), me.getBoxFillColor()).append(); canvas.drawLine(Math.round((lwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 2), Math.round((q1 - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 2), lineColor).append(); canvas.drawLine(Math.round((lwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 4), Math.round((lwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight - canvasHeight / 4), whiskerColor).append(); canvas.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 2), Math.round((q3 - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 2), lineColor).append(); canvas.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight / 4), Math.round((rwhisker - minValue) * unitSize + canvasLeft), Math.round(canvasHeight - canvasHeight / 4), whiskerColor).append(); canvas.drawLine(Math.round((q2 - minValue) * unitSize + canvasLeft), Math.round(canvasHeight * 0.1), Math.round((q2 - minValue) * unitSize + canvasLeft), Math.round(canvasHeight * 0.9), me.getMedianColor()).append(); if (me.target) { size = Math.ceil(me.spotRadius); canvas.drawLine(Math.round((me.target - minValue) * unitSize + canvasLeft), Math.round((canvasHeight / 2) - size), Math.round((me.target - minValue) * unitSize + canvasLeft), Math.round((canvasHeight / 2) + size), targetColor).append(); canvas.drawLine(Math.round((me.target - minValue) * unitSize + canvasLeft - size), Math.round(canvasHeight / 2), Math.round((me.target - minValue) * unitSize + canvasLeft + size), Math.round(canvasHeight / 2), targetColor).append(); } if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) { me.currentRegion = null; me.updateDisplay(); } canvas.render(); } }); Ext.define('Ext.sparkline.Bullet', { extend: 'Ext.sparkline.Base', alias: 'widget.sparklinebullet', config: { targetColor: '#f33', targetWidth: 3, performanceColor: '#33f', rangeColors: [ '#d3dafe', '#a8b6ff', '#7f94ff' ], base: null, tipTpl: new Ext.XTemplate('{fieldkey:this.fields} - {value}', { fields: function(v) { if (v === 'r') { return 'Range'; } if (v === 'p') { return 'Performance'; } if (v === 't') { return 'Target'; } } }) }, applyValues: function(newValues) { newValues = Ext.Array.map(Ext.Array.from(newValues), this.normalizeValue); this.disabled = !(newValues && newValues.length); return newValues; }, onUpdate: function() { var me = this, values = me.values, min, max, vals, base = me.getBase(); me.callParent(arguments); vals = values.slice(); vals[0] = vals[0] === null ? vals[2] : vals[0]; vals[1] = values[1] === null ? vals[2] : vals[1]; min = Math.min.apply(Math, values); max = Math.max.apply(Math, values); if (base == null) { min = min < 0 ? min : 0; } else { min = base; } me.min = min; me.max = max; me.range = max - min; me.shapes = {}; me.valueShapes = {}; me.regiondata = {}; if (!values.length) { me.disabled = true; } }, getRegion: function(x, y) { var shapeid = this.canvas.getShapeAt(x, y); return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined; }, getRegionFields: function(region) { return { fieldkey: region.substr(0, 1), value: this.values[region.substr(1)], region: region }; }, renderHighlight: function(region) { switch (region.substr(0, 1)) { case 'r': this.renderRange(region.substr(1), true).append(); break; case 'p': this.renderPerformance(true).append(); break; case 't': this.renderTarget(true).append(); break; } }, renderRange: function(region, highlight) { var rangeval = this.values[region], rangewidth = Math.round(this.getWidth() * ((rangeval - this.min) / this.range)), color = this.getRangeColors()[region - 2]; if (highlight) { color = this.calcHighlightColor(color); } return this.canvas.drawRect(0, 0, rangewidth - 1, this.getHeight() - 1, color, color); }, renderPerformance: function(highlight) { var perfval = this.values[1], perfwidth = Math.round(this.getWidth() * ((perfval - this.min) / this.range)), color = this.getPerformanceColor(); if (highlight) { color = this.calcHighlightColor(color); } return this.canvas.drawRect(0, Math.round(this.getHeight() * 0.3), perfwidth - 1, Math.round(this.getHeight() * 0.4) - 1, color, color); }, renderTarget: function(highlight) { var targetval = this.values[0], targetWidth = this.getTargetWidth(), x = Math.round(this.getWidth() * ((targetval - this.min) / this.range) - (targetWidth / 2)), targettop = Math.round(this.getHeight() * 0.1), targetheight = this.getHeight() - (targettop * 2), color = this.getTargetColor(); if (highlight) { color = this.calcHighlightColor(color); } return this.canvas.drawRect(x, targettop, targetWidth - 1, targetheight - 1, color, color); }, renderGraph: function() { var me = this, vlen = me.values.length, canvas = me.canvas, i, shape, shapes = me.shapes || (me.shapes = {}), valueShapes = me.valueShapes || (me.valueShapes = {}); if (!me.callParent()) { return; } for (i = 2; i < vlen; i++) { shape = me.renderRange(i).append(); shapes[shape.id] = 'r' + i; valueShapes['r' + i] = shape.id; } if (me.values[1] !== null) { shape = me.renderPerformance().append(); shapes[shape.id] = 'p1'; valueShapes.p1 = shape.id; } if (me.values[0] !== null) { shape = this.renderTarget().append(); shapes[shape.id] = 't0'; valueShapes.t0 = shape.id; } if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) { me.updateDisplay(); } canvas.render(); } }); Ext.define('Ext.sparkline.Discrete', { extend: 'Ext.sparkline.BarBase', alias: 'widget.sparklinediscrete', config: { lineHeight: 'auto', thresholdColor: null, thresholdValue: 0, chartRangeMax: null, chartRangeMin: null, chartRangeClip: false, tipTpl: new Ext.XTemplate('{prefix}{value}{suffix}') }, applyValues: function(newValues) { newValues = Ext.Array.map(Ext.Array.from(newValues), Number); this.disabled = !(newValues && newValues.length); return newValues; }, onUpdate: function() { var me = this, values = me.values, chartRangeMin = me.getChartRangeMin(), chartRangeMax = me.getChartRangeMax(), chartRangeClip = me.getChartRangeClip(); me.callParent(arguments); me.regionShapes = {}; me.min = Math.min.apply(Math, values); me.max = Math.max.apply(Math, values); me.range = me.max - me.min; me.width = me.getWidth(); me.interval = Math.floor(me.width / values.length); me.itemWidth = me.width / values.length; if (chartRangeMin != null && (chartRangeClip || chartRangeMin < me.min)) { me.min = chartRangeMin; } if (chartRangeMax != null && (chartRangeClip || chartRangeMax > me.max)) { me.max = chartRangeMax; } if (me.canvas) { if (me.getLineHeight() === 'auto') { me.setLineHeight(Math.round(me.getHeight() * 0.3)); } } }, getRegion: function(x, y) { return Math.floor(x / this.itemWidth); }, getRegionFields: function(region) { return { isNull: this.values[region] === undefined, value: this.values[region], offset: region }; }, renderRegion: function(valuenum, highlight) { var me = this, values = me.values, min = me.min, max = me.max, range = me.range, interval = me.interval, canvas = me.canvas, canvasHeight = me.getHeight(), lineHeight = me.getLineHeight(), pheight = canvasHeight - lineHeight, ytop, val, color, x, thresholdColor = me.getThresholdColor(); val = Ext.Number.constrain(values[valuenum], min, max); x = valuenum * interval; ytop = Math.round(pheight - pheight * ((val - min) / range)); color = (thresholdColor && val < me.getThresholdValue()) ? thresholdColor : me.getLineColor(); if (highlight) { color = me.calcHighlightColor(color); } canvas.drawLine(x, ytop, x, ytop + lineHeight, color).append(); } }); Ext.define('Ext.sparkline.Line', { extend: 'Ext.sparkline.Base', requires: [ 'Ext.sparkline.RangeMap' ], alias: 'widget.sparklineline', config: { spotColor: '#f80', highlightSpotColor: '#5f5', highlightLineColor: '#f22', spotRadius: 1.5, minSpotColor: '#f80', maxSpotColor: '#f80', lineWidth: 1, normalRangeMin: null, normalRangeMax: null, normalRangeColor: '#ccc', drawNormalOnTop: false, chartRangeMin: null, chartRangeMax: null, chartRangeMinX: null, chartRangeMaxX: null, tipTpl: new Ext.XTemplate('● {prefix}{y}{suffix}'), valueSpots: null }, applyValueSpots: function(valueSpots) { if (valueSpots && !valueSpots.get) { valueSpots = new Ext.sparkline.RangeMap(valueSpots); } return valueSpots; }, onUpdate: function() { this.vertices = []; this.regionMap = []; this.xvalues = []; this.yvalues = []; this.yminmax = []; }, getRegion: function(x, y) { var i, regionMap = this.regionMap; for (i = regionMap.length; i--; ) { if (regionMap[i] !== null && x >= regionMap[i][0] && x <= regionMap[i][1]) { return regionMap[i][2]; } } return undefined; }, getRegionFields: function(region) { return { isNull: this.yvalues[region] === null, x: this.xvalues[region], y: this.yvalues[region], color: this.getLineColor(), fillColor: this.getFillColor(), offset: region }; }, renderHighlight: function(region) { var me = this, canvas = me.canvas, vertex = me.vertices[region], spotRadius = me.getSpotRadius(), highlightSpotColor = me.getHighlightSpotColor(), highlightLineColor = me.getHighlightLineColor(); if (!vertex) { return; } if (spotRadius && highlightSpotColor) { canvas.drawCircle(vertex[0], vertex[1], spotRadius, null, highlightSpotColor).append(); } if (highlightLineColor) { canvas.drawLine(vertex[0], me.canvasTop, vertex[0], me.canvasTop + me.getHeight(), highlightLineColor).append(); } }, scanValues: function() { var me = this, values = me.values, valcount = values.length, xvalues = me.xvalues, yvalues = me.yvalues, yminmax = me.yminmax, i, val, isStr, isArray, sp; for (i = 0; i < valcount; i++) { val = values[i]; isStr = typeof (values[i]) === 'string'; isArray = typeof (values[i]) === 'object' && values[i] instanceof Array; sp = isStr && values[i].split(':'); if (isStr && sp.length === 2) { xvalues.push(Number(sp[0])); yvalues.push(Number(sp[1])); yminmax.push(Number(sp[1])); } else if (isArray) { xvalues.push(val[0]); yvalues.push(val[1]); yminmax.push(val[1]); } else { xvalues.push(i); if (values[i] === null || values[i] === 'null') { yvalues.push(null); } else { yvalues.push(Number(val)); yminmax.push(Number(val)); } } } if (me.xvalues) { xvalues = me.xvalues; } me.maxy = me.maxyorg = Math.max.apply(Math, yminmax); me.miny = me.minyorg = Math.min.apply(Math, yminmax); me.maxx = Math.max.apply(Math, xvalues); me.minx = Math.min.apply(Math, xvalues); me.xvalues = xvalues; me.yvalues = yvalues; me.yminmax = yminmax; }, processRangeOptions: function() { var me = this, normalRangeMin = me.getNormalRangeMin(), normalRangeMax = me.getNormalRangeMax(), chartRangeMin = me.getChartRangeMin(), chartRangeMinX = me.getChartRangeMinX(), chartRangeMax = me.getChartRangeMax(), chartRangeMaxX = me.getChartRangeMaxX(); if (normalRangeMin != null) { if (normalRangeMin < me.miny) { me.miny = normalRangeMin; } if (normalRangeMax > me.maxy) { me.maxy = normalRangeMax; } } if (chartRangeMin != null && (me.chartRangeClip || chartRangeMin < me.miny)) { me.miny = chartRangeMin; } if (chartRangeMax != null && (me.chartRangeClip || chartRangeMax > me.maxy)) { this.maxy = chartRangeMax; } if (chartRangeMinX != null && (me.chartRangeClipX || chartRangeMinX < me.minx)) { me.minx = chartRangeMinX; } if (chartRangeMaxX != null && (me.chartRangeClipX || chartRangeMaxX > me.maxx)) { me.maxx = chartRangeMaxX; } }, drawNormalRange: function(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) { var normalRangeMin = this.getNormalRangeMin(), normalRangeMax = this.getNormalRangeMax(), ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))), height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey); this.canvas.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.normalRangeColor).append(); }, renderGraph: function() { var me = this, canvas = me.canvas, canvasWidth = me.getWidth(), canvasHeight = me.getHeight(), vertices = me.vertices, spotRadius = me.getSpotRadius(), regionMap = me.regionMap, rangeX, Y, yvallast, canvasTop, canvasLeft, vertex, path, paths, x, y, xNext, xPos, xPosNext, last, next, yValCount, lineShapes, fillShapes, plen, valueSpots = me.getValueSpots(), hlSpotsEnabled, color, xValues, yValues, i, spotColor = me.getSpotColor(), minSpotColor = me.getMinSpotColor(), maxSpotColor = me.getMaxSpotColor(), normalRangeMin = me.getNormalRangeMin(), drawNormalOnTop = me.getDrawNormalOnTop(); if (!me.callParent()) { return; } me.scanValues(); me.processRangeOptions(); xValues = me.xvalues; yValues = me.yvalues; if (!me.yminmax.length || me.yvalues.length < 2) { return; } canvasTop = canvasLeft = 0; rangeX = me.maxx - me.minx === 0 ? 1 : me.maxx - me.minx; Y = me.maxy - me.miny === 0 ? 1 : me.maxy - me.miny; yvallast = me.yvalues.length - 1; if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) { spotRadius = 0; } if (spotRadius) { hlSpotsEnabled = me.getHighlightSpotColor() && !me.disableInteraction; if (hlSpotsEnabled || minSpotColor || (spotColor && yValues[yvallast] === me.miny)) { canvasHeight -= Math.ceil(spotRadius); } if (hlSpotsEnabled || maxSpotColor || (spotColor && yValues[yvallast] === me.maxy)) { canvasHeight -= Math.ceil(spotRadius); canvasTop += Math.ceil(spotRadius); } if (hlSpotsEnabled || ((minSpotColor || maxSpotColor) && (yValues[0] === me.miny || yValues[0] === me.maxy))) { canvasLeft += Math.ceil(spotRadius); canvasWidth -= Math.ceil(spotRadius); } if (hlSpotsEnabled || spotColor || (minSpotColor || maxSpotColor && (yValues[yvallast] === me.miny || yValues[yvallast] === me.maxy))) { canvasWidth -= Math.ceil(spotRadius); } } canvasHeight--; if (normalRangeMin != null && !drawNormalOnTop) { me.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, Y); } path = []; paths = [ path ]; last = next = null; yValCount = yValues.length; for (i = 0; i < yValCount; i++) { x = xValues[i]; xNext = xValues[i + 1]; y = yValues[i]; xPos = canvasLeft + Math.round((x - me.minx) * (canvasWidth / rangeX)); xPosNext = i < yValCount - 1 ? canvasLeft + Math.round((xNext - me.minx) * (canvasWidth / rangeX)) : canvasWidth; next = xPos + ((xPosNext - xPos) / 2); regionMap[i] = [ last || 0, next, i ]; last = next; if (y === null) { if (i) { if (yValues[i - 1] !== null) { path = []; paths.push(path); } vertices.push(null); } } else { if (y < me.miny) { y = me.miny; } if (y > me.maxy) { y = me.maxy; } if (!path.length) { path.push([ xPos, canvasTop + canvasHeight ]); } vertex = [ xPos, canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / Y))) ]; path.push(vertex); vertices.push(vertex); } } lineShapes = []; fillShapes = []; plen = paths.length; for (i = 0; i < plen; i++) { path = paths[i]; if (path.length) { if (me.fillColor) { path.push([ path[path.length - 1][0], (canvasTop + canvasHeight) ]); fillShapes.push(path.slice(0)); path.pop(); } if (path.length > 2) { path[0] = [ path[0][0], path[1][1] ]; } lineShapes.push(path); } } plen = fillShapes.length; for (i = 0; i < plen; i++) { canvas.drawShape(fillShapes[i], me.fillColor, me.fillColor).append(); } if (normalRangeMin != null && drawNormalOnTop) { me.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, Y); } plen = lineShapes.length; for (i = 0; i < plen; i++) { canvas.drawShape(lineShapes[i], me.getLineColor(), null, me.getLineWidth()).append(); } if (spotRadius && valueSpots) { if (valueSpots.get == null) { valueSpots = new Ext.sparkline.RangeMap(valueSpots); } for (i = 0; i < yValCount; i++) { color = valueSpots.get(yValues[i]); if (color) { canvas.drawCircle(canvasLeft + Math.round((xValues[i] - me.minx) * (canvasWidth / rangeX)), canvasTop + Math.round(canvasHeight - (canvasHeight * ((yValues[i] - me.miny) / Y))), spotRadius, null, color).append(); } } } if (spotRadius && spotColor && yValues[yvallast] != null) { canvas.drawCircle(canvasLeft + Math.round((xValues[xValues.length - 1] - me.minx) * (canvasWidth / rangeX)), canvasTop + Math.round(canvasHeight - (canvasHeight * ((yValues[yvallast] - me.miny) / Y))), spotRadius, null, spotColor).append(); } if (me.maxy !== me.minyorg) { if (spotRadius && minSpotColor) { x = xValues[Ext.Array.indexOf(yValues, me.minyorg)]; canvas.drawCircle(canvasLeft + Math.round((x - me.minx) * (canvasWidth / rangeX)), canvasTop + Math.round(canvasHeight - (canvasHeight * ((me.minyorg - me.miny) / Y))), spotRadius, null, minSpotColor).append(); } if (spotRadius && maxSpotColor) { x = xValues[Ext.Array.indexOf(yValues, me.maxyorg)]; canvas.drawCircle(canvasLeft + Math.round((x - me.minx) * (canvasWidth / rangeX)), canvasTop + Math.round(canvasHeight - (canvasHeight * ((me.maxyorg - me.miny) / Y))), spotRadius, null, maxSpotColor).append(); } } me.canvasTop = canvasTop; if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) { me.updateDisplay(); } canvas.render(); } }); Ext.define('Ext.sparkline.Pie', { extend: 'Ext.sparkline.Base', alias: 'widget.sparklinepie', config: { offset: 0, sliceColors: [ '#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00', '#dd4477', '#0099c6', '#990099' ], borderWidth: 0, borderColor: '#000', tipTpl: new Ext.XTemplate('● {value} ({percent:number("0.0")}%)') }, applyValues: function(newValues) { newValues = Ext.Array.map(Ext.Array.from(newValues), Number); this.disabled = !(newValues && newValues.length); return newValues; }, onUpdate: function() { var me = this, values = me.values, total = 0, i; me.callParent(arguments); me.shapes = {}; me.valueShapes = {}; if (values.length > 0) { for (i = values.length; i--; ) { total += values[i]; } } me.total = total; me.radius = Math.floor(Math.min(me.getWidth(), me.getHeight()) / 2); }, getRegion: function(x, y) { var ratio = window.devicePixelRatio || 1, shapeid = this.canvas.getShapeAt(x * ratio, y * ratio); return (shapeid != null && this.shapes[shapeid] != null) ? this.shapes[shapeid] : null; }, getRegionFields: function(region) { var sliceColors = this.getSliceColors(); return { isNull: this.values[region] == null, value: this.values[region], percent: this.values[region] / this.total * 100, color: sliceColors[region % sliceColors.length], offset: region }; }, renderHighlight: function(region) { this.renderSlice(region, true).append(); }, renderSlice: function(valuenum, highlight) { var me = this, canvas = me.canvas, radius = me.radius, borderWidth = me.getBorderWidth(), offset = me.getOffset(), circle = 2 * Math.PI, values = me.values, total = me.total, next = offset ? (2 * Math.PI) * (offset / 360) : 0, start, end, i, vlen, color, sliceColors = this.getSliceColors(); vlen = values.length; for (i = 0; i < vlen; i++) { start = next; end = next; if (total > 0) { end = next + (circle * (values[i] / total)); } if (valuenum === i) { color = sliceColors[i % sliceColors.length]; if (highlight) { color = me.calcHighlightColor(color); } return canvas.drawPieSlice(radius, radius, radius - borderWidth, start, end, null, color); } next = end; } }, renderGraph: function() { var me = this, canvas = me.canvas, values = me.values, radius = me.radius, borderWidth = me.getBorderWidth(), shape, i, shapes = me.shapes || (me.shapes = {}), valueShapes = me.valueShapes || (me.valueShapes = {}); if (!me.callParent()) { return; } if (borderWidth) { canvas.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)), me.getBorderColor(), null, borderWidth).append(); } for (i = values.length; i--; ) { if (values[i]) { shape = me.renderSlice(i).append(); valueShapes[i] = shape.id; shapes[shape.id] = i; } } if (me.currentPageXY && me.el.getRegion().contains(me.currentPageXY)) { me.currentRegion = null; me.updateDisplay(); } canvas.render(); } }); Ext.define('Ext.sparkline.TriState', { extend: 'Ext.sparkline.BarBase', requires: [ 'Ext.sparkline.RangeMap' ], alias: 'widget.sparklinetristate', config: { barWidth: 4, barSpacing: 1, posBarColor: '#6f6', negBarColor: '#f44', zeroBarColor: '#999', colorMap: {}, tipTpl: new Ext.XTemplate('● {value:this.states}', { states: function(v) { var value = Number(v); if (value === -1) { return 'Loss'; } if (value === 0) { return 'Draw'; } if (value === 1) { return 'Win'; } return v; } }) }, applyColorMap: function(colorMap) { var me = this; if (Ext.isArray(colorMap)) { me.colorMapByIndex = colorMap; me.colorMapByValue = null; } else { me.colorMapByIndex = null; me.colorMapByValue = colorMap; if (me.colorMapByValue && me.colorMapByValue.get == null) { me.colorMapByValue = new Ext.sparkline.RangeMap(colorMap); } } return colorMap; }, applyValues: function(newValues) { newValues = Ext.Array.map(Ext.Array.from(newValues), Number); this.disabled = !(newValues && newValues.length); return newValues; }, onUpdate: function() { this.totalBarWidth = this.getBarWidth() + this.getBarSpacing(); }, getBarWidth: function() { var values = this.values; return this._barWidth || (this.getWidth() - (values.length - 1) * this.getBarSpacing()) / values.length; }, getRegion: function(x, y) { return Math.floor(x / this.totalBarWidth); }, getRegionFields: function(region) { return { isNull: this.values[region] == null, value: this.values[region], color: this.calcColor(this.values[region], region), offset: region }; }, calcColor: function(value, valuenum) { var me = this, values = me.values, colorMapByIndex = me.colorMapByIndex, colorMapByValue = me.colorMapByValue, color, newColor; if (colorMapByValue && (newColor = colorMapByValue.get(value))) { color = newColor; } else if (colorMapByIndex && colorMapByIndex.length > valuenum) { color = colorMapByIndex[valuenum]; } else if (values[valuenum] < 0) { color = me.getNegBarColor(); } else if (values[valuenum] > 0) { color = me.getPosBarColor(); } else { color = me.getZeroBarColor(); } return color; }, renderRegion: function(valuenum, highlight) { var me = this, values = me.values, canvas = me.canvas, canvasHeight, height, halfHeight, x, y, color; canvasHeight = canvas.pixelHeight; halfHeight = Math.round(canvasHeight / 2); x = valuenum * me.totalBarWidth; if (values[valuenum] < 0) { y = halfHeight; height = halfHeight - 1; } else if (values[valuenum] > 0) { y = 0; height = halfHeight - 1; } else { y = halfHeight - 1; height = 2; } color = me.calcColor(values[valuenum], valuenum); if (color == null) { return; } if (highlight) { color = me.calcHighlightColor(color); } canvas.drawRect(x, y, me.getBarWidth() - 1, height - 1, color, color).append(); } }); Ext.define('Ext.state.CookieProvider', { extend: 'Ext.state.Provider', constructor: function(config) { var me = this; me.path = "/"; me.expires = new Date(Ext.Date.now() + (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); }, clear: function(name) { this.clearCookie(name); this.callParent(arguments); }, 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; }, setCookie: function(name, value) { var me = this; document.cookie = me.prefix + name + "=" + me.encodeValue(value) + ((me.expires == null) ? "" : ("; expires=" + me.expires.toUTCString())) + ((me.path == null) ? "" : ("; path=" + me.path)) + ((me.domain == null) ? "" : ("; domain=" + me.domain)) + (me.secure ? "; secure" : ""); }, clearCookie: function(name) { var me = this; document.cookie = me.prefix + name + "=null; expires=Thu, 01-Jan-1970 00:00:01 GMT" + ((me.path == null) ? "" : ("; path=" + me.path)) + ((me.domain == null) ? "" : ("; domain=" + me.domain)) + (me.secure ? "; secure" : ""); } }); Ext.define('Ext.state.LocalStorageProvider', { extend: 'Ext.state.Provider', requires: [ 'Ext.util.LocalStorage' ], alias: 'state.localstorage', constructor: function() { var me = this; me.callParent(arguments); me.store = me.getStorageObject(); if (me.store) { me.state = me.readLocalStorage(); } else { me.state = {}; } }, readLocalStorage: function() { var store = this.store, data = {}, keys = store.getKeys(), i = keys.length, key; while (i--) { key = keys[i]; data[key] = this.decodeValue(store.getItem(key)); } return data; }, set: function(name, value) { var me = this; me.clear(name); if (value != null) { me.store.setItem(name, me.encodeValue(value)); me.callParent(arguments); } }, clear: function(name) { this.store.removeItem(name); this.callParent(arguments); }, getStorageObject: function() { var prefix = this.prefix, id = prefix, n = id.length - 1; if (id.charAt(n) === '-') { id = id.substring(0, n); } return new Ext.util.LocalStorage({ id: id, prefix: prefix }); } }); Ext.define('Ext.toolbar.Breadcrumb', { extend: 'Ext.Container', xtype: 'breadcrumb', requires: [ 'Ext.data.TreeStore', 'Ext.button.Split' ], mixins: [ 'Ext.util.FocusableContainer' ], isBreadcrumb: true, baseCls: Ext.baseCSSPrefix + 'breadcrumb', layout: 'hbox', config: { buttonUI: 'plain-toolbar', displayField: 'text', overflowHandler: null, showIcons: null, showMenuIcons: null, store: null, useSplitButtons: true }, renderConfig: { selection: 'root' }, publishes: [ 'selection' ], twoWayBindable: [ 'selection' ], _breadcrumbCls: Ext.baseCSSPrefix + 'breadcrumb', _btnCls: Ext.baseCSSPrefix + 'breadcrumb-btn', _folderIconCls: Ext.baseCSSPrefix + 'breadcrumb-icon-folder', _leafIconCls: Ext.baseCSSPrefix + 'breadcrumb-icon-leaf', initComponent: function() { var me = this, layout = me.layout, overflowHandler = me.getOverflowHandler(); if (typeof layout === 'string') { layout = { type: layout }; } if (overflowHandler) { layout.overflowHandler = overflowHandler; } me.layout = layout; me.defaultButtonUI = me.getButtonUI(); me._buttons = []; me.addCls([ me._breadcrumbCls, me._breadcrumbCls + '-' + me.ui ]); me.callParent(); }, onDestroy: function() { var me = this; me._buttons = Ext.destroy(me._buttons); me.setStore(null); me.callParent(); }, afterComponentLayout: function() { var me = this, overflowHandler = me.layout.overflowHandler; me.callParent(arguments); if (overflowHandler && me.tooNarrow && overflowHandler.scrollToItem) { overflowHandler.scrollToItem(me.getSelection().get('depth')); } }, applySelection: function(node) { var store = this.getStore(); if (store) { node = (node === 'root') ? this.getStore().getRoot() : node; } else { node = null; } return node; }, updateSelection: function(node) { var me = this, buttons = me._buttons, items = [], itemCount = me.items.getCount(), needsSync = me._needsSync, displayField = me.getDisplayField(), showIcons, glyph, iconCls, icon, newItemCount, currentNode, text, button, id, depth, i; Ext.suspendLayouts(); if (node) { currentNode = node; depth = node.get('depth'); newItemCount = depth + 1; i = depth; while (currentNode) { id = currentNode.getId(); button = buttons[i]; if (!needsSync && button && button._breadcrumbNodeId === id) { break; } text = currentNode.get(displayField); if (button) { button.setText(text); } else { button = buttons[i] = Ext.create({ xtype: me.getUseSplitButtons() ? 'splitbutton' : 'button', ui: me.getButtonUI(), cls: me._btnCls + ' ' + me._btnCls + '-' + me.ui, text: text, showEmptyMenu: true, menu: { listeners: { click: '_onMenuClick', beforeshow: '_onMenuBeforeShow', scope: this } }, handler: '_onButtonClick', scope: me }); } showIcons = this.getShowIcons(); if (showIcons !== false) { glyph = currentNode.get('glyph'); icon = currentNode.get('icon'); iconCls = currentNode.get('iconCls'); if (glyph) { button.setGlyph(glyph); button.setIcon(null); button.setIconCls(iconCls); } else if (icon) { button.setGlyph(null); button.setIconCls(null); button.setIcon(icon); } else if (iconCls) { button.setGlyph(null); button.setIcon(null); button.setIconCls(iconCls); } else if (showIcons) { button.setGlyph(null); button.setIcon(null); button.setIconCls((currentNode.isLeaf() ? me._leafIconCls : me._folderIconCls) + '-' + me.ui); } else { button.setGlyph(null); button.setIcon(null); button.setIconCls(null); } } button.setArrowVisible(currentNode.hasChildNodes()); button._breadcrumbNodeId = currentNode.getId(); currentNode = currentNode.parentNode; i--; } if (newItemCount > itemCount) { items = buttons.slice(itemCount, depth + 1); me.add(items); } else { for (i = itemCount - 1; i >= newItemCount; i--) { me.remove(me.items.items[i], false); } } } else { me.removeAll(false); } Ext.resumeLayouts(true); me.fireEvent('selectionchange', me, node); me._needsSync = false; }, applyUseSplitButtons: function(useSplitButtons, oldUseSplitButtons) { if (this.rendered && useSplitButtons !== oldUseSplitButtons) { Ext.Error.raise("Cannot reconfigure 'useSplitButtons' config of Ext.toolbar.Breadcrumb after initial render"); } return useSplitButtons; }, applyStore: function(store) { if (store) { store = Ext.data.StoreManager.lookup(store); } return store; }, updateStore: function(store, oldStore) { this._needsSync = true; if (store && !this.isConfiguring) { this.setSelection(store.getRoot()); } }, updateOverflowHandler: function(overflowHandler) { if (overflowHandler === 'menu') { Ext.Error.raise("Using Menu overflow with breadcrumb is not currently supported."); } }, privates: { _onButtonClick: function(button, e) { if (this.getUseSplitButtons()) { this.setSelection(this.getStore().getNodeById(button._breadcrumbNodeId)); } }, _onMenuClick: function(menu, item, e) { if (item) { this.setSelection(this.getStore().getNodeById(item._breadcrumbNodeId)); } }, _onMenuBeforeShow: function(menu) { var me = this, node = me.getStore().getNodeById(menu.ownerCmp._breadcrumbNodeId), displayField = me.getDisplayField(), showMenuIcons = me.getShowMenuIcons(), childNodes, child, glyph, items, i, icon, iconCls, ln, item; if (node.hasChildNodes()) { childNodes = node.childNodes; items = []; for (i = 0 , ln = childNodes.length; i < ln; i++) { child = childNodes[i]; item = { text: child.get(displayField), _breadcrumbNodeId: child.getId() }; if (showMenuIcons !== false) { glyph = child.get('glyph'); icon = child.get('icon'); iconCls = child.get('iconCls'); if (glyph) { item.glyph = glyph; item.iconCls = iconCls; } else if (icon) { item.icon = icon; } else if (iconCls) { item.iconCls = iconCls; } else if (showMenuIcons) { item.iconCls = (child.isLeaf() ? me._leafIconCls : me._folderIconCls) + '-' + me.ui; } } items.push(item); } menu.removeAll(); menu.add(items); } else { return false; } } } }); Ext.define('Ext.toolbar.Fill', { extend: 'Ext.Component', requires: [ 'Ext.toolbar.Toolbar' ], alias: 'widget.tbfill', alternateClassName: 'Ext.Toolbar.Fill', ariaRole: 'presentation', isFill: true, flex: 1 }); Ext.define('Ext.toolbar.Spacer', { extend: 'Ext.Component', requires: [ 'Ext.toolbar.Toolbar' ], alias: 'widget.tbspacer', alternateClassName: 'Ext.Toolbar.Spacer', baseCls: Ext.baseCSSPrefix + 'toolbar-spacer', ariaRole: 'presentation' }); Ext.define('Ext.view.DragZone', { extend: 'Ext.dd.DragZone', containerScroll: false, constructor: function(config) { var me = this, view, ownerCt, el; Ext.apply(me, config); if (!me.ddGroup) { me.ddGroup = 'view-dd-zone-' + me.view.id; } view = me.view; ownerCt = view.ownerCt; if (ownerCt) { el = ownerCt.getTargetEl().dom; } else { el = view.el.dom.parentNode; } me.callParent([ el ]); me.ddel = document.createElement('div'); me.ddel.className = Ext.baseCSSPrefix + 'grid-dd-wrap'; }, init: function(id, sGroup, config) { var me = this, triggerEvent = Ext.supports.touchScroll ? 'itemlongpress' : 'itemmousedown', eventSpec = { scope: me }; eventSpec[triggerEvent] = me.onItemMouseDown; me.initTarget(id, sGroup, config); me.view.mon(me.view, eventSpec); }, onValidDrop: function(target, e, id) { this.callParent([ target, e, id ]); target.el.focus(); }, onItemMouseDown: function(view, record, item, index, e) { if (!this.isPreventDrag(e, record, item, index)) { if (view.focusRow) { view.focusRow(record); } this.handleMouseDown(e); } }, isPreventDrag: function(e, record, item, index) { return false; }, getDragData: function(e) { var view = this.view, item = e.getTarget(view.getItemSelector()); if (item) { return { copy: view.copy || (view.allowCopy && e.ctrlKey), event: e, view: view, ddel: this.ddel, item: item, records: view.getSelectionModel().getSelection(), fromPosition: Ext.fly(item).getXY() }; } }, onInitDrag: function(x, y) { var me = this, data = me.dragData, view = data.view, selectionModel = view.getSelectionModel(), record = view.getRecord(data.item); if (!selectionModel.isSelected(record)) { selectionModel.selectWithEvent(record, me.DDMInstance.mousedownEvent); } data.records = selectionModel.getSelection(); Ext.fly(me.ddel).setHtml(me.getDragText()); me.proxy.update(me.ddel); me.onStartDrag(x, y); return true; }, getDragText: function() { var count = this.dragData.records.length; return Ext.String.format(this.dragText, count, count === 1 ? '' : 's'); }, 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); }, getDragText: function() { var records = this.dragData.records, count = records.length, text = records[0].get(this.displayField), suffix = 's'; if (count === 1 && text) { return text; } else if (!text) { suffix = ''; } return Ext.String.format(this.dragText, count, suffix); }, afterRepair: function() { var me = this, view = me.view, selectedRowCls = view.selectedItemCls, records = me.dragData.records, r, rLen = records.length, fly = Ext.fly, item; if (Ext.enableFx && me.repairHighlight) { for (r = 0; r < rLen; r++) { item = view.getNode(records[r]); 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.define('Ext.tree.ViewDropZone', { extend: 'Ext.view.DropZone', allowParentInserts: false, allowContainerDrops: false, appendOnly: false, expandDelay: 500, indicatorCls: Ext.baseCSSPrefix + 'tree-ddindicator', expandNode: function(node) { var view = this.view; this.expandProcId = false; if (!node.isLeaf() && !node.isExpanded()) { view.expand(node); this.expandProcId = false; } }, queueExpand: function(node) { this.expandProcId = Ext.Function.defer(this.expandNode, this.expandDelay, this, [ node ]); }, cancelExpand: function() { if (this.expandProcId) { clearTimeout(this.expandProcId); this.expandProcId = false; } }, getPosition: function(e, node) { var view = this.view, record = view.getRecord(node), y = e.getY(), noAppend = record.isLeaf(), noBelow = false, region = Ext.fly(node).getRegion(), fragment; if (record.isRoot()) { return 'append'; } if (this.appendOnly) { return noAppend ? false : 'append'; } if (!this.allowParentInserts) { noBelow = record.hasChildNodes() && record.isExpanded(); } fragment = (region.bottom - region.top) / (noAppend ? 2 : 3); if (y >= region.top && y < (region.top + fragment)) { return 'before'; } else if (!noBelow && (noAppend || (y >= (region.bottom - fragment) && y <= region.bottom))) { return 'after'; } else { return 'append'; } }, isValidDropPoint: function(node, position, dragZone, e, data) { if (!node || !data.item) { return false; } var view = this.view, targetNode = view.getRecord(node), draggedRecords = data.records, dataLength = draggedRecords.length, ln = draggedRecords.length, i, record; if (!(targetNode && position && dataLength)) { return false; } for (i = 0; i < ln; i++) { record = draggedRecords[i]; if (record.isNode && record.contains(targetNode)) { return false; } } if (position === 'append' && targetNode.get('allowDrop') === false) { return false; } else if (position !== 'append' && targetNode.parentNode.get('allowDrop') === false) { return false; } if (Ext.Array.contains(draggedRecords, targetNode)) { return false; } return view.fireEvent('nodedragover', targetNode, position, data, e) !== false; }, 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(), indicatorY = 0; this.cancelExpand(); if (position === 'append' && !this.expandProcId && !Ext.Array.contains(data.records, targetNode) && !targetNode.isLeaf() && !targetNode.isExpanded()) { this.queueExpand(targetNode); } 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 (view.touchScroll === 2) { indicatorY += view.getScrollY(); } if (position === 'before') { returnCls = targetNode.isFirst() ? Ext.baseCSSPrefix + 'tree-drop-ok-above' : Ext.baseCSSPrefix + 'tree-drop-ok-between'; indicator.showAt(0, indicatorY); dragZone.proxy.show(); } else if (position === 'after') { returnCls = targetNode.isLast() ? Ext.baseCSSPrefix + 'tree-drop-ok-below' : Ext.baseCSSPrefix + 'tree-drop-ok-between'; indicatorY += Ext.fly(node).getHeight(); indicator.showAt(0, indicatorY); dragZone.proxy.show(); } else { returnCls = Ext.baseCSSPrefix + 'tree-drop-ok-append'; indicator.hide(); } } else { this.valid = false; } this.currentCls = returnCls; return returnCls; }, onNodeOut: function(n, dd, e, data) { this.valid = false; this.getIndicator().hide(); }, onContainerOver: function(dd, e, data) { return this.allowContainerDrops ? this.dropAllowed : e.getTarget('.' + this.indicatorCls) ? this.currentCls : this.dropNotAllowed; }, onContainerDrop: function(dragZone, e, data) { if (this.allowContainerDrops) { this.valid = true; this.currentPosition = 'append'; this.overRecord = this.view.store.getRoot(); this.onNodeDrop(this.overRecord, dragZone, e, data); } }, notifyOut: function() { this.callParent(arguments); this.cancelExpand(); }, handleNodeDrop: function(data, targetNode, position) { var me = this, targetView = me.view, parentNode = targetNode ? targetNode.parentNode : targetView.panel.getRootNode(), Model = targetView.store.getModel(), records, i, len, record, insertionMethod, argList, needTargetExpand, transferData; if (data.copy) { records = data.records; data.records = []; for (i = 0 , len = records.length; i < len; i++) { record = records[i]; if (record.isNode) { data.records.push(record.copy()); } else { data.records.push(new Model(Ext.apply({}, record.data))); } } } me.cancelExpand(); if (position === 'before') { insertionMethod = parentNode.insertBefore; argList = [ null, targetNode ]; targetNode = parentNode; } 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() || targetNode.isLoading())) { needTargetExpand = true; } insertionMethod = targetNode.appendChild; argList = [ null ]; } transferData = function() { var color, n; Ext.suspendLayouts(); for (i = 0 , len = data.records.length; i < len; i++) { record = data.records[i]; if (!record.isNode) { if (record.isModel) { record = new Model(record.data, record.getId()); } else { record = new Model(record); } data.records[i] = record; } argList[0] = record; insertionMethod.apply(targetNode, argList); targetView.getNavigationModel().setPosition(record); } if (me.sortOnDrop) { targetNode.sort(targetNode.getOwnerTree().store.getSorters().sortFn); } Ext.resumeLayouts(true); if (Ext.enableFx && me.dropHighlight) { color = me.dropHighlightColor; for (i = 0; i < len; i++) { n = targetView.getNode(data.records[i]); if (n) { Ext.fly(n).highlight(color); } } } }; if (needTargetExpand) { targetNode.expand(false, transferData); } else if (targetNode.isLoading()) { targetNode.on({ expand: transferData, delay: 1, single: true }); } else { transferData(); } } }); Ext.define('Ext.tree.plugin.TreeViewDragDrop', { extend: 'Ext.plugin.Abstract', alias: 'plugin.treeviewdragdrop', uses: [ 'Ext.tree.ViewDragZone', 'Ext.tree.ViewDropZone' ], dragText: '{0} selected node{1}', allowParentInserts: false, allowContainerDrops: false, appendOnly: false, ddGroup: "TreeDD", containerScroll: false, expandDelay: 1000, enableDrop: true, enableDrag: true, nodeHighlightColor: 'c3daf9', nodeHighlightOnDrop: Ext.enableFx, displayField: 'text', init: function(view) { view.on('render', this.onViewRender, this, { single: true }); }, destroy: function() { Ext.destroy(this.dragZone, this.dropZone); }, onViewRender: function(view) { var me = this, scrollEl; if (me.enableDrag) { if (me.containerScroll) { scrollEl = view.getEl(); } me.dragZone = new Ext.tree.ViewDragZone(Ext.apply({ view: view, ddGroup: me.dragGroup || me.ddGroup, dragText: me.dragText, displayField: me.displayField, repairHighlightColor: me.nodeHighlightColor, repairHighlight: me.nodeHighlightOnRepair, scrollEl: scrollEl }, me.dragZone)); } if (me.enableDrop) { me.dropZone = new Ext.tree.ViewDropZone(Ext.apply({ 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, sortOnDrop: me.sortOnDrop, containerScroll: me.containerScroll }, me.dropZone)); } } }, function() { var proto = this.prototype; proto.nodeHighlightOnDrop = proto.nodeHighlightOnRepair = Ext.enableFx; }); Ext.define('Ext.util.CSS', function() { var CSS, rules = null, doc = document, camelRe = /(-[a-z])/gi, camelFn = function(m, a) { return a.charAt(1).toUpperCase(); }; return { singleton: true, rules: rules, initialized: false, constructor: function() { CSS = this; }, 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); } ss = styleEl.styleSheet; if (ss) { head.appendChild(styleEl); ss.cssText = cssText; } else { styleEl.appendChild(doc.createTextNode(cssText)); head.appendChild(styleEl); ss = styleEl.sheet; } CSS.cacheStyleSheet(ss); return ss; }, removeStyleSheet: function(id) { var existing = doc.getElementById(id); if (existing) { existing.parentNode.removeChild(existing); } }, swapStyleSheet: function(id, url) { var ss; CSS.removeStyleSheet(id); 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); }, cacheStyleSheet: function(ss) { if (!rules) { rules = CSS.rules = {}; } try { var ssRules = ss.cssRules || ss.rules, i = ssRules.length - 1, imports = ss.imports, len = imports ? imports.length : 0, rule, j; for (j = 0; j < len; ++j) { CSS.cacheStyleSheet(imports[j]); } for (; i >= 0; --i) { rule = ssRules[i]; if (rule.styleSheet) { CSS.cacheStyleSheet(rule.styleSheet); } CSS.cacheRule(rule, ss); } } catch (e) {} }, cacheRule: function(cssRule, styleSheet) { if (cssRule.styleSheet) { return CSS.cacheStyleSheet(cssRule.styleSheet); } var selectorText = cssRule.selectorText, selectorCount, j; if (selectorText) { selectorText = selectorText.split(','); selectorCount = selectorText.length; for (j = 0; j < selectorCount; j++) { rules[Ext.String.trim(selectorText[j]).toLowerCase()] = { parentStyleSheet: styleSheet, cssRule: cssRule }; } } }, getRules: function(refreshCache) { var result = {}, selector; if (rules === null || refreshCache) { CSS.refreshCache(); } for (selector in rules) { result[selector] = rules[selector].cssRule; } return result; }, refreshCache: function() { var ds = doc.styleSheets, i = 0, len = ds.length; rules = CSS.rules = {}; for (; i < len; i++) { try { if (!ds[i].disabled) { CSS.cacheStyleSheet(ds[i]); } } catch (e) {} } }, getRule: function(selector, refreshCache, rawCache) { var i, result; if (!rules || refreshCache) { CSS.refreshCache(); } if (!Ext.isArray(selector)) { result = rules[selector.toLowerCase()]; if (result && !rawCache) { result = result.cssRule; } return result || null; } for (i = 0; i < selector.length; i++) { if (rules[selector[i]]) { return rawCache ? rules[selector[i].toLowerCase()] : rules[selector[i].toLowerCase()].cssRule; } } return null; }, createRule: function(styleSheet, selector, cssText) { var result, ruleSet = styleSheet.cssRules || styleSheet.rules, index = ruleSet.length; if (styleSheet.insertRule) { styleSheet.insertRule(selector + ' {' + cssText + '}', index); } else { styleSheet.addRule(selector, cssText || ' '); } CSS.cacheRule(result = ruleSet[index], styleSheet); return result; }, updateRule: function(selector, property, value) { var rule, i, styles; if (!Ext.isArray(selector)) { rule = CSS.getRule(selector); if (rule) { if (arguments.length === 2) { styles = Ext.Element.parseStyles(property); for (property in styles) { rule.style[property.replace(camelRe, camelFn)] = styles[property]; } } else { rule.style[property.replace(camelRe, camelFn)] = value; } return true; } } else { for (i = 0; i < selector.length; i++) { if (CSS.updateRule(selector[i], property, value)) { return true; } } } return false; }, deleteRule: function(selector) { var rule = CSS.getRule(selector, false, true), styleSheet, index; if (rule) { styleSheet = rule.parentStyleSheet; index = Ext.Array.indexOf(styleSheet.cssRules || styleSheet.rules, rule.cssRule); if (styleSheet.deleteRule) { styleSheet.deleteRule(index); } else { styleSheet.removeRule(index); } delete rules[selector]; } } }; }); Ext.define('Ext.util.Cookies', { singleton: true, 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.toUTCString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : ""); }, get: function(name) { var parts = document.cookie.split('; '), len = parts.length, item, i, ret; for (i = 0; i < len; ++i) { item = parts[i].split('='); if (item[0] === name) { ret = item[1]; return ret ? unescape(ret) : ''; } } return null; }, clear: function(name, path) { if (this.get(name)) { path = path || '/'; document.cookie = name + '=' + '; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=' + path; } } }); Ext.define('Ext.view.MultiSelectorSearch', { extend: 'Ext.panel.Panel', xtype: 'multiselector-search', layout: 'fit', floating: true, resizable: true, minWidth: 200, minHeight: 200, border: true, defaultListenerScope: true, referenceHolder: true, searchText: 'Search...', initComponent: function() { var me = this, owner = me.owner, items = me.makeItems(), i, item, records, store; me.dockedItems = me.makeDockedItems(); me.items = items; store = Ext.data.StoreManager.lookup(me.store); for (i = items.length; i--; ) { if ((item = items[i]).xtype === 'grid') { item.store = store; item.isSearchGrid = true; item.selModel = item.selModel || { type: 'checkboxmodel', pruneRemoved: false, listeners: { selectionchange: 'onSelectionChange' } }; Ext.merge(item, me.grid); if (!item.columns) { item.hideHeaders = true; item.columns = [ { flex: 1, dataIndex: me.field } ]; } break; } } me.callParent(); records = me.getOwnerStore().getRange(); if (!owner.convertSelectionRecord.$nullFn) { for (i = records.length; i--; ) { records[i] = owner.convertSelectionRecord(records[i]); } } if (store.isLoading() || (store.loadCount === 0 && !store.getCount())) { store.on('load', function() { var len = records.length, i, record, toSelect = []; if (!me.destroyed) { for (i = 0; i < len; i++) { record = store.getById(records[i].getId()); if (record) { toSelect.push(record); } } me.selectRecords(toSelect); } }, null, { single: true }); } else { me.selectRecords(records); } }, getOwnerStore: function() { return this.owner.getStore(); }, afterShow: function() { var searchField = this.lookupReference('searchField'); this.callParent(arguments); if (searchField) { searchField.focus(); } }, getSearchStore: function() { var searchGrid = this.lookupReference('searchGrid'); return searchGrid.getStore(); }, makeDockedItems: function() { return [ { xtype: 'textfield', reference: 'searchField', dock: 'top', hideFieldLabel: true, emptyText: this.searchText, triggers: { clear: { cls: Ext.baseCSSPrefix + 'form-clear-trigger', handler: 'onClearSearch', hidden: true } }, listeners: { change: 'onSearchChange', buffer: 300 } } ]; }, makeItems: function() { return [ { xtype: 'grid', reference: 'searchGrid', trailingBufferZone: 2, leadingBufferZone: 2, viewConfig: { deferEmptyText: false, emptyText: 'No results.' } } ]; }, selectRecords: function(records) { var searchGrid = this.lookupReference('searchGrid'); return searchGrid.getSelectionModel().select(records); }, deselectRecords: function(records) { var searchGrid = this.lookupReference('searchGrid'); return searchGrid.getSelectionModel().deselect(records); }, search: function(text) { var me = this, filter = me.searchFilter, filters = me.getSearchStore().getFilters(); if (text) { filters.beginUpdate(); if (filter) { filter.setValue(text); } else { me.searchFilter = filter = new Ext.util.Filter({ id: 'search', property: me.field, value: text }); } filters.add(filter); filters.endUpdate(); } else if (filter) { filters.remove(filter); } }, privates: { onClearSearch: function() { var searchField = this.lookupReference('searchField'); searchField.setValue(null); searchField.focus(); }, onSearchChange: function(searchField) { var value = searchField.getValue(), trigger = searchField.getTrigger('clear'); trigger.setHidden(!value); this.search(value); }, onSelectionChange: function(selModel, selection) { var owner = this.owner, store = owner.getStore(), data = store.data, remove = 0, map = {}, add, i, id, record; for (i = selection.length; i--; ) { record = selection[i]; id = record.id; map[id] = record; if (!data.containsKey(id)) { (add || (add = [])).push(owner.convertSearchRecord(record)); } } for (i = data.length; i--; ) { record = data.getAt(i); if (!map[record.id]) { (remove || (remove = [])).push(record); } } if (add || remove) { data.splice(data.length, remove, add); } } } }); Ext.define('Ext.view.MultiSelector', { extend: 'Ext.grid.Panel', xtype: 'multiselector', config: { search: { xtype: 'multiselector-search', width: 200, height: 200, store: { autoLoad: true } } }, fieldName: 'name', fieldTitle: null, removeRowText: '✖', removeRowTip: 'Remove this item', emptyText: 'Nothing selected', addToolText: 'Search for items to add', initComponent: function() { var me = this, emptyText = me.emptyText, store = me.getStore(), search = me.getSearch(), fieldTitle = me.fieldTitle, searchStore, model; if (!search) { Ext.Error.raise('The search configuration is required for the multi selector'); } searchStore = search.store; if (searchStore.isStore) { model = searchStore.getModel(); } else { model = searchStore.model; } if (!store) { me.store = { model: model }; } if (emptyText && !me.viewConfig) { me.viewConfig = { deferEmptyText: false, emptyText: emptyText }; } if (!me.columns) { me.hideHeaders = !fieldTitle; me.columns = [ { text: fieldTitle, dataIndex: me.fieldName, flex: 1 }, me.makeRemoveRowColumn() ]; } me.callParent(); }, addTools: function() { this.addTool({ type: 'plus', tooltip: this.addToolText, callback: 'onShowSearch', scope: this }); }, convertSearchRecord: Ext.identityFn, convertSelectionRecord: Ext.identityFn, makeRemoveRowColumn: function() { var me = this; return { width: 22, menuDisabled: true, tdCls: Ext.baseCSSPrefix + 'multiselector-remove', processEvent: me.processRowEvent.bind(me), renderer: me.renderRemoveRow, updater: Ext.emptyFn, scope: me }; }, processRowEvent: function(type, view, cell, recordIndex, cellIndex, e, record, row) { if (e.type !== 'click') { return; } if (Ext.fly(cell).hasCls(Ext.baseCSSPrefix + 'multiselector-remove')) { this.store.remove(record); if (this.searchPopup) { this.searchPopup.deselectRecords(record); } } }, renderRemoveRow: function() { return '' + this.removeRowText + ''; }, beforeDestroy: function() { Ext.un({ mousedown: 'onDismissSearch', scope: this }); this.callParent(); }, privates: { onDismissSearch: function(e) { var searchPopup = this.searchPopup; if (searchPopup && !(searchPopup.owns(e.getTarget()) || this.owns(e.getTarget()))) { Ext.un({ mousedown: 'onDismissSearch', scope: this }); searchPopup.hide(); } }, onShowSearch: function(panel, tool) { var me = this, searchPopup = me.searchPopup, store = me.getStore(); if (!searchPopup) { searchPopup = Ext.merge({ owner: me, field: me.fieldName, floating: true }, me.getSearch()); me.searchPopup = searchPopup = me.add(searchPopup); if (store.getCount()) { searchPopup.selectRecords(store.getRange()); } } searchPopup.showBy(me, 'tl-tr?'); Ext.on({ mousedown: 'onDismissSearch', scope: me }); } } }); Ext.define('Ext.window.Toast', { extend: 'Ext.window.Window', xtype: 'toast', isToast: true, cls: Ext.baseCSSPrefix + 'toast', bodyPadding: 10, autoClose: true, plain: false, draggable: false, resizable: false, shadow: false, focus: Ext.emptyFn, anchor: null, useXAxis: false, align: 'br', animate: true, spacing: 6, paddingX: 30, paddingY: 10, slideInAnimation: 'easeIn', slideBackAnimation: 'bounceOut', slideInDuration: 1500, slideBackDuration: 1000, hideDuration: 500, autoCloseDelay: 3000, stickOnClick: true, stickWhileHover: true, closeOnMouseDown: false, isHiding: false, isFading: false, destroyAfterHide: false, closeOnMouseOut: false, xPos: 0, yPos: 0, initComponent: function() { var me = this; me.updateAlignment(me.align); me.setAnchor(me.anchor); me.callParent(); }, onRender: function() { var me = this; me.callParent(arguments); me.el.hover(me.onMouseEnter, me.onMouseLeave, me); if (me.closeOnMouseDown) { Ext.getDoc().on('mousedown', me.onDocumentMousedown, me); } }, alignmentProps: { br: { paddingFactorX: -1, paddingFactorY: -1, siblingAlignment: "br-br", anchorAlign: "tr-br" }, bl: { paddingFactorX: 1, paddingFactorY: -1, siblingAlignment: "bl-bl", anchorAlign: "tl-bl" }, tr: { paddingFactorX: -1, paddingFactorY: 1, siblingAlignment: "tr-tr", anchorAlign: "br-tr" }, tl: { paddingFactorX: 1, paddingFactorY: 1, siblingAlignment: "tl-tl", anchorAlign: "bl-tl" }, b: { paddingFactorX: 0, paddingFactorY: -1, siblingAlignment: "b-b", useXAxis: 0, anchorAlign: "t-b" }, t: { paddingFactorX: 0, paddingFactorY: 1, siblingAlignment: "t-t", useXAxis: 0, anchorAlign: "b-t" }, l: { paddingFactorX: 1, paddingFactorY: 0, siblingAlignment: "l-l", useXAxis: 1, anchorAlign: "r-l" }, r: { paddingFactorX: -1, paddingFactorY: 0, siblingAlignment: "r-r", useXAxis: 1, anchorAlign: "l-r" }, x: { br: { anchorAlign: "bl-br" }, bl: { anchorAlign: "br-bl" }, tr: { anchorAlign: "tl-tr" }, tl: { anchorAlign: "tr-tl" } } }, updateAlignment: function(align) { var me = this, alignmentProps = me.alignmentProps, props = alignmentProps[align], xprops = alignmentProps.x[align]; if (xprops && me.useXAxis) { Ext.applyIf(me, xprops); } Ext.applyIf(me, props); }, getXposAlignedToAnchor: function() { var me = this, align = me.align, anchor = me.anchor, anchorEl = anchor && anchor.el, el = me.el, xPos = 0; if (anchorEl && anchorEl.dom) { if (!me.useXAxis) { xPos = el.getLeft(); } else if (align === 'br' || align === 'tr' || align === 'r') { xPos += anchorEl.getAnchorXY('r')[0]; xPos -= (el.getWidth() + me.paddingX); } else { xPos += anchorEl.getAnchorXY('l')[0]; xPos += me.paddingX; } } return xPos; }, getYposAlignedToAnchor: function() { var me = this, align = me.align, anchor = me.anchor, anchorEl = anchor && anchor.el, el = me.el, yPos = 0; if (anchorEl && anchorEl.dom) { if (me.useXAxis) { yPos = el.getTop(); } else if (align === 'br' || align === 'bl' || align === 'b') { yPos += anchorEl.getAnchorXY('b')[1]; yPos -= (el.getHeight() + me.paddingY); } else { yPos += anchorEl.getAnchorXY('t')[1]; yPos += me.paddingY; } } return yPos; }, getXposAlignedToSibling: function(sibling) { var me = this, align = me.align, el = me.el, xPos; if (!me.useXAxis) { xPos = el.getLeft(); } else if (align === 'tl' || align === 'bl' || align === 'l') { xPos = (sibling.xPos + sibling.el.getWidth() + sibling.spacing); } else { xPos = (sibling.xPos - el.getWidth() - me.spacing); } return xPos; }, getYposAlignedToSibling: function(sibling) { var me = this, align = me.align, el = me.el, yPos; if (me.useXAxis) { yPos = el.getTop(); } else if (align === 'tr' || align === 'tl' || align === 't') { yPos = (sibling.yPos + sibling.el.getHeight() + sibling.spacing); } else { yPos = (sibling.yPos - el.getHeight() - sibling.spacing); } return yPos; }, getToasts: function() { var anchor = this.anchor, alignment = this.anchorAlign, activeToasts = anchor.activeToasts || (anchor.activeToasts = {}); return activeToasts[alignment] || (activeToasts[alignment] = []); }, setAnchor: function(anchor) { var me = this, Toast; me.anchor = anchor = ((typeof anchor === 'string') ? Ext.getCmp(anchor) : anchor); if (!anchor) { Toast = Ext.window.Toast; me.anchor = Toast.bodyAnchor || (Toast.bodyAnchor = { el: Ext.getBody() }); } }, beforeShow: function() { var me = this; if (me.stickOnClick) { me.body.on('click', function() { me.cancelAutoClose(); }); } if (me.autoClose) { if (!me.closeTask) { me.closeTask = new Ext.util.DelayedTask(me.doAutoClose, me); } me.closeTask.delay(me.autoCloseDelay); } me.el.setX(-10000); me.el.setOpacity(1); }, afterShow: function() { var me = this, el = me.el, activeToasts, sibling, length, xy; me.callParent(arguments); activeToasts = me.getToasts(); length = activeToasts.length; sibling = length && activeToasts[length - 1]; if (sibling) { el.alignTo(sibling.el, me.siblingAlignment, [ 0, 0 ]); me.xPos = me.getXposAlignedToSibling(sibling); me.yPos = me.getYposAlignedToSibling(sibling); } else { el.alignTo(me.anchor.el, me.anchorAlign, [ (me.paddingX * me.paddingFactorX), (me.paddingY * me.paddingFactorY) ], false); me.xPos = me.getXposAlignedToAnchor(); me.yPos = me.getYposAlignedToAnchor(); } Ext.Array.include(activeToasts, me); if (me.animate) { xy = el.getXY(); el.animate({ from: { x: xy[0], y: xy[1] }, to: { x: me.xPos, y: me.yPos, opacity: 1 }, easing: me.slideInAnimation, duration: me.slideInDuration, dynamic: true }); } else { me.setLocalXY(me.xPos, me.yPos); } }, onDocumentMousedown: function(e) { if (this.isVisible() && !this.owns(e.getTarget())) { this.hide(); } }, slideBack: function() { var me = this, anchor = me.anchor, anchorEl = anchor && anchor.el, el = me.el, activeToasts = me.getToasts(), index = Ext.Array.indexOf(activeToasts, me); if (!me.isHiding && el && el.dom && anchorEl && anchorEl.isVisible()) { if (index) { me.xPos = me.getXposAlignedToSibling(activeToasts[index - 1]); me.yPos = me.getYposAlignedToSibling(activeToasts[index - 1]); } else { me.xPos = me.getXposAlignedToAnchor(); me.yPos = me.getYposAlignedToAnchor(); } me.stopAnimation(); if (me.animate) { el.animate({ to: { x: me.xPos, y: me.yPos }, easing: me.slideBackAnimation, duration: me.slideBackDuration, dynamic: true }); } } }, update: function() { var me = this; if (me.isVisible()) { me.isHiding = true; me.hide(); } me.callParent(arguments); me.show(); }, cancelAutoClose: function() { var closeTask = this.closeTask; if (closeTask) { closeTask.cancel(); } }, doAutoClose: function() { var me = this; if (!(me.stickWhileHover && me.mouseIsOver)) { me.close(); } else { me.closeOnMouseOut = true; } }, onMouseEnter: function() { this.mouseIsOver = true; }, onMouseLeave: function() { var me = this; me.mouseIsOver = false; if (me.closeOnMouseOut) { me.closeOnMouseOut = false; me.close(); } }, removeFromAnchor: function() { var me = this, activeToasts, index; if (me.anchor) { activeToasts = me.getToasts(); index = Ext.Array.indexOf(activeToasts, me); if (index !== -1) { Ext.Array.erase(activeToasts, index, 1); for (; index < activeToasts.length; index++) { activeToasts[index].slideBack(); } } } }, getFocusEl: Ext.emptyFn, hide: function() { var me = this, el = me.el; me.cancelAutoClose(); if (me.isHiding) { if (!me.isFading) { me.callParent(arguments); me.removeFromAnchor(); me.isHiding = false; } } else { me.isHiding = true; me.isFading = true; me.cancelAutoClose(); if (el) { if (me.animate) { el.fadeOut({ opacity: 0, easing: 'easeIn', duration: me.hideDuration, listeners: { afteranimate: function() { me.isFading = false; me.hide(me.animateTarget, me.doClose, me); } } }); } else { me.isFading = false; me.hide(me.animateTarget, me.doClose, me); } } } return me; } }, function(Toast) { Ext.toast = function(message, title, align, iconCls) { var config = message, toast; if (Ext.isString(message)) { config = { title: title, html: message, iconCls: iconCls }; if (align) { config.align = align; } } toast = new Toast(config); toast.show(); return toast; }; });