/* This file is part of Ext JS 6.6.0.258 Copyright (c) 2011-2018 Sencha Inc license: http://www.sencha.com/legal/sencha-software-license-agreement Contact: http://www.sencha.com/contact Commercial Usage Licensees holding valid commercial licenses may use this file in accordance with the Commercial Software License Agreement referenced above or, alternatively, in accordance with the terms contained in a written agreement between you and Sencha. If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact. Version: 6.6.0.258 Build date: 2018-06-19 05:16:53 (a26fc5ffb54acf6e1afd5f18c467b14161985898) */ // @tag core var Ext = Ext || {}; Ext.Boot = Ext.Boot || (function(emptyFn) { var doc = document, _emptyArray = [], _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: 'UTF-8' }, _assetConfig = {}, cssRe = /\.css(?:\?|$)/i, resolverEl = doc.createElement('a'), isBrowser = typeof window !== 'undefined', _environment = { browser: isBrowser, node: !isBrowser && (typeof require === 'function'), phantom: (window && (window._phantom || window.callPhantom)) || /PhantomJS/.test(window.navigator.userAgent) }, _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; }, _merge = function() { var lowerCase = false, obj = Array.prototype.shift.call(arguments), index, i, len, value; if (typeof arguments[arguments.length - 1] === 'boolean') { lowerCase = Array.prototype.pop.call(arguments); } len = arguments.length; for (index = 0; index < len; index++) { value = arguments[index]; if (typeof value === 'object') { for (i in value) { obj[lowerCase ? i.toLowerCase() : i] = value[i]; } } } return obj; }, _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; }, Boot = { loading: 0, loaded: 0, apply: _apply, env: _environment, config: _config, assetConfig: _assetConfig, scripts: {}, currentFile: null, suspendedQueue: [], currentRequest: null, syncMode: false, debug: _debug, useElements: true, listeners: [], Request: Request, Entry: Entry, allowMultipleBrowsers: false, browserNames: { ie: 'IE', firefox: 'Firefox', safari: 'Safari', chrome: 'Chrome', opera: 'Opera', dolfin: 'Dolfin', edge: 'Edge', webosbrowser: 'webOSBrowser', chromeMobile: 'ChromeMobile', chromeiOS: 'ChromeiOS', silk: 'Silk', other: 'Other' }, osNames: { ios: 'iOS', android: 'Android', windowsPhone: 'WindowsPhone', webos: 'webOS', blackberry: 'BlackBerry', rimTablet: 'RIMTablet', mac: 'MacOS', win: 'Windows', tizen: 'Tizen', linux: 'Linux', bada: 'Bada', chromeOS: 'ChromeOS', other: 'Other' }, browserPrefixes: { ie: 'MSIE ', edge: 'Edge/', firefox: 'Firefox/', chrome: 'Chrome/', safari: 'Version/', opera: 'OPR/', dolfin: 'Dolfin/', webosbrowser: 'wOSBrowser/', chromeMobile: 'CrMo/', chromeiOS: 'CriOS/', silk: 'Silk/' }, browserPriority: [ 'edge', 'opera', 'dolfin', 'webosbrowser', 'silk', 'chromeiOS', 'chromeMobile', 'ie', 'firefox', 'safari', 'chrome' ], osPrefixes: { 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/', chromeOS: 'CrOS ' }, fallbackOSPrefixes: { windows: 'win', mac: 'mac', linux: 'linux' }, devicePrefixes: { iPhone: 'iPhone', iPod: 'iPod', iPad: 'iPad' }, maxIEVersion: 12, detectPlatformTags: function() { var me = this, ua = navigator.userAgent, isMobile = /Mobile(\/|\s)/.test(ua), element = document.createElement('div'), 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; }, getBrowsers = function() { var browsers = {}, maxIEVersion, prefix, value, key, index, len, match, version, matched; len = me.browserPriority.length; for (index = 0; index < len; index++) { key = me.browserPriority[index]; if (!matched) { value = me.browserPrefixes[key]; match = ua.match(new RegExp('(' + value + ')([\\w\\._]+)')); version = match && match.length > 1 ? parseInt(match[2]) : 0; if (version) { matched = true; } } else { version = 0; } browsers[key] = version; } if (browsers.ie) { var mode = document.documentMode; if (mode >= 8) { browsers.ie = mode; } } version = browsers.ie || false; maxIEVersion = Math.max(version, me.maxIEVersion); for (index = 8; index <= maxIEVersion; ++index) { prefix = 'ie' + index; browsers[prefix + 'm'] = version ? version <= index : 0; browsers[prefix] = version ? version === index : 0; browsers[prefix + 'p'] = version ? version >= index : 0; } return browsers; }, getOperatingSystems = function() { var systems = {}, value, key, keys, index, len, match, matched, version, activeCount; keys = _getKeys(me.osPrefixes); len = keys.length; for (index = 0 , activeCount = 0; index < len; index++) { key = keys[index]; value = me.osPrefixes[key]; match = ua.match(new RegExp('(' + value + ')([^\\s;]+)')); matched = match ? match[1] : null; if (matched && (matched === 'HTC_' || matched === 'Silk/')) { version = 2.3; } else { version = match && match.length > 1 ? parseFloat(match[match.length - 1]) : 0; } if (version) { activeCount++; } systems[key] = version; } keys = _getKeys(me.fallbackOSPrefixes); len = keys.length; for (index = 0; index < len; index++) { key = keys[index]; if (activeCount === 0) { value = me.fallbackOSPrefixes[key]; match = ua.toLowerCase().match(new RegExp(value)); systems[key] = match ? true : 0; } else { systems[key] = 0; } } return systems; }, getDevices = function() { var devices = {}, value, key, keys, index, len, match; keys = _getKeys(me.devicePrefixes); len = keys.length; for (index = 0; index < len; index++) { key = keys[index]; value = me.devicePrefixes[key]; match = ua.match(new RegExp(value)); devices[key] = match ? true : 0; } return devices; }, browsers = getBrowsers(), systems = getOperatingSystems(), devices = getDevices(), platformParams = Boot.loadPlatformsParam(); _merge(_tags, browsers, systems, devices, platformParams, true); _tags.phone = !!((_tags.iphone || _tags.ipod) || (!_tags.silk && (_tags.android && (_tags.android < 3 || isMobile))) || (_tags.blackberry && isMobile) || (_tags.windowsphone)); _tags.tablet = !!(!_tags.phone && (_tags.ipad || _tags.android || _tags.silk || _tags.rimtablet || (_tags.ie10 && /; Touch/.test(ua)))); _tags.touch = isEventSupported('touchend') || navigator.maxTouchPoints || navigator.msMaxTouchPoints; _tags.desktop = !_tags.phone && !_tags.tablet; _tags.cordova = _tags.phonegap = !!(window.PhoneGap || window.Cordova || window.cordova); _tags.webview = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)(?!.*FBAN)/i.test(ua); _tags.androidstock = (_tags.android <= 4.3) && (_tags.safari || _tags.silk); _merge(_tags, platformParams, true); }, 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.platformTags.split(","); for (tmplen = tmpArray.length , i = 0; i < tmplen; i++) { platform = tmpArray[i].split(":"); name = platform[0]; enabled = true; if (platform.length > 1) { enabled = platform[1]; if (enabled === 'false' || enabled === '0') { enabled = false; } } platforms[name] = enabled; } } return platforms; }, filterPlatform: function(platform, excludes) { platform = _emptyArray.concat(platform || _emptyArray); excludes = _emptyArray.concat(excludes || _emptyArray); var plen = platform.length, elen = excludes.length, include = (!plen && elen), i, tag; for (i = 0; i < plen && !include; i++) { tag = platform[i]; include = !!_tags[tag]; } for (i = 0; i < elen && include; i++) { tag = excludes[i]; include = !_tags[tag]; } return include; }, init: function() { var scriptEls = doc.getElementsByTagName('script'), script = scriptEls[0], len = scriptEls.length, re = /\/ext(\-[a-z\-]+)?\.js$/, entry, src, state, baseUrl, key, n, origin; Boot.hasReadyState = ("readyState" in script); Boot.hasAsync = ("async" in script); Boot.hasDefer = ("defer" in script); Boot.hasOnLoad = ("onload" in script); Boot.isIE8 = Boot.hasReadyState && !Boot.hasAsync && Boot.hasDefer && !Boot.hasOnLoad; Boot.isIE9 = Boot.hasReadyState && !Boot.hasAsync && Boot.hasDefer && Boot.hasOnLoad; Boot.isIE10p = Boot.hasReadyState && Boot.hasAsync && Boot.hasDefer && Boot.hasOnLoad; if (Boot.isIE8) { Boot.isIE10 = false; Boot.isIE10m = true; } else { Boot.isIE10 = (new Function('/*@cc_on return @_jscript_version @*/')()) === 10; Boot.isIE10m = Boot.isIE10 || Boot.isIE9 || Boot.isIE8; } Boot.isIE11 = Boot.isIE10p && !Boot.isIE10; for (n = 0; n < len; n++) { src = (script = scriptEls[n]).src; if (!src) { continue; } state = script.readyState || null; if (!baseUrl && re.test(src)) { baseUrl = src; } if (!Boot.scripts[key = Boot.canonicalUrl(src)]) { 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.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, canonicalPath) { var key, entry; key = canonicalPath ? url : Boot.canonicalUrl(url); entry = Boot.scripts[key]; if (!entry) { entry = Boot.create(url, key, cfg); if (canonicalPath) { entry.canonicalPath = true; } } return entry; }, registerContent: function(url, type, content) { var cfg = { content: content, loaded: true, css: type === 'css' }; return Boot.getEntry(url, cfg); }, processRequest: function(request, sync) { request.loadEntries(sync); }, load: function(request) { var request = new Request(request); if (request.sync || Boot.syncMode) { return Boot.loadSync(request); } if (Boot.currentRequest) { request.getEntries(); Boot.suspendedQueue.push(request); } else { Boot.currentRequest = request; Boot.processRequest(request, false); } return Boot; }, loadSync: function(request) { 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) { 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) { if (!('length' in indexMap)) { var indexArray = [], index; for (index in indexMap) { if (!isNaN(+index)) { indexArray[+index] = indexMap[index]; } } indexMap = indexArray; } 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.onreadystatechange = emptyFn; xhr = null; } }; if (async) { xhr.onreadystatechange = readyStateChange; } try { 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(this, cfg); delete this.url; this.urls = urls; this.charset = charset; } 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(item, indexMap, loadOrder, includeUses, skipLoaded) { var resolved = [], queue = [ item ], itemIndex = item.idx, queue, entry, dependencies, depIndex, i, len; if (indexMap[itemIndex]) { return resolved; } indexMap[itemIndex] = resolved[itemIndex] = true; while (item = queue.shift()) { if (item.canonicalPath) { entry = Boot.getEntry(item.path, null, true); } else { entry = Boot.getEntry(this.prepareUrl(item.path)); } if (!(skipLoaded && entry.done)) { if (includeUses && item.uses && item.uses.length) { dependencies = item.requires.concat(item.uses); } else { dependencies = item.requires; } for (i = 0 , len = dependencies.length; i < len; i++) { depIndex = dependencies[i]; if (!indexMap[depIndex]) { indexMap[depIndex] = resolved[depIndex] = true; queue.push(loadOrder[depIndex]); } } } } return resolved; }, getPathsFromIndexes: function(indexes, loadOrder) { var paths = [], index, len; for (index = 0 , len = indexes.length; index < len; index++) { if (indexes[index]) { paths.push(loadOrder[index].path); } } return paths; }, expandUrl: function(url, loadOrder, loadOrderMap, indexMap, includeUses, skipLoaded) { var item, resolved; if (loadOrder) { item = loadOrderMap[url]; if (item) { resolved = this.getLoadIndexes(item, indexMap, loadOrder, includeUses, skipLoaded); if (resolved.length) { return this.getPathsFromIndexes(resolved, loadOrder); } } } return [ url ]; }, expandUrls: function(urls, includeUses) { var me = this, loadOrder = me.loadOrder, expanded = [], expandMap = {}, indexMap = [], loadOrderMap, tmpExpanded, i, len, t, tlen, tUrl; if (typeof urls === "string") { urls = [ urls ]; } if (loadOrder) { loadOrderMap = me.loadOrderMap; if (!loadOrderMap) { loadOrderMap = me.loadOrderMap = me.createLoadOrderMap(loadOrder); } } for (i = 0 , len = urls.length; i < len; i++) { tmpExpanded = this.expandUrl(urls[i], loadOrder, loadOrderMap, indexMap, includeUses, false); 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, loadOrderMap, item, i, entry, urls, url; if (!entries) { entries = []; urls = me.getUrls(); if (me.loadOrder) { loadOrderMap = me.loadOrderMap; } for (i = 0; i < urls.length; i++) { url = me.prepareUrl(urls[i]); if (loadOrderMap) { item = loadOrderMap[url]; } entry = Boot.getEntry(url, { buster: me.buster, charset: me.charset }, item && item.canonicalPath); 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, entries, 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) { while ((listener = listeners.shift())) { listener(this); } } } }; function Entry(cfg) { if (cfg.$isEntry) { return cfg; } 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 (Boot.config.disableCaching) { 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(this, cfg); this.charset = charset; this.buster = buster; this.requests = []; } Entry.prototype = { $isEntry: true, done: false, evaluated: false, loaded: false, isCrossDomain: function() { var me = this; if (me.crossDomain === undefined) { me.crossDomain = (me.getLoadUrl().indexOf(Boot.origin) !== 0); } return me.crossDomain; }, isCss: function() { var me = this; if (me.css === undefined) { if (me.url) { var assetConfig = Boot.assetConfig[me.url]; me.css = assetConfig ? assetConfig.type === "css" : cssRe.test(me.url); } else { me.css = false; } } return this.css; }, getElement: function(tag) { var me = this, el = me.el; if (!el) { 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 (me.charset) { el.charset = me.charset; } if (Boot.hasAsync) { el.async = false; } } me.el = el; } return el; }, getLoadUrl: function() { var me = this, url; url = me.canonicalPath ? me.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(); me.preserve = true; el.onerror = function() { me.error = true; if (callback) { callback(); callback = null; } }; if (Boot.isIE10m) { el.onreadystatechange = function() { if (this.readyState === 'loaded' || this.readyState === 'complete') { if (callback) { callback(); callback = this.onreadystatechange = this.onerror = null; } } }; } else { el.onload = function() { callback(); callback = this.onload = this.onerror = null; }; } el[me.prop] = me.getLoadUrl(); }, onLoadElementReady: function() { Boot.getHead().appendChild(this.getElement()); this.evaluated = true; }, inject: function(content, asset) { 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.el.onerror = me.el.onload = emptyFn; me.el = null; me.loaded = me.evaluated = me.done = true; me.notifyRequests(); }; me.createLoadElement(function() { complete(); }); me.evaluateLoadElement(); return false; }, loadElement: function() { var me = this, complete = function() { me.el.onerror = me.el.onload = emptyFn; me.el = null; me.loaded = me.evaluated = me.done = true; me.notifyRequests(); }; 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 (Boot.isIE10 || me.isCrossDomain()) { return me.loadCrossDomain(); } else if (!me.isCss() && Boot.hasReadyState) { me.createLoadElement(function() { me.loaded = true; me.notifyRequests(); }); } else if (Boot.useElements && !(me.isCss() && _environment.phantom)) { 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) { 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 || '/'); }; 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; }()); } Ext.setResourcePath = function(poolName, path) { var manifest = Ext.manifest || (Ext.manifest = {}), paths = manifest.resources || (manifest.resources = {}); if (manifest) { if (typeof poolName !== 'string') { Ext.apply(paths, poolName); } else { paths[poolName] = path; } manifest.resources = paths; } }; Ext.getResourcePath = function(path, poolName, packageName) { if (typeof path !== 'string') { poolName = path.pool; packageName = path.packageName; path = path.path; } var manifest = Ext.manifest, paths = manifest && manifest.resources, poolPath = paths[poolName], output = []; if (poolPath == null) { poolPath = paths.path; if (poolPath == null) { poolPath = 'resources'; } } if (poolPath) { output.push(poolPath); } if (packageName) { output.push(packageName); } output.push(path); return output.join('/'); }; var Ext = Ext || {}; (function() { var global = this, objectPrototype = Object.prototype, toString = objectPrototype.toString, enumerables = [ 'valueOf', 'toLocaleString', 'toString', 'constructor' ], emptyFn = Ext.fireIdle = 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})?\)\\?\/$/, elevateArgs, elevateFn, elevateRet, elevateScope; Ext.global = global; Ext.$nextIid = 0; Ext.now = Date.now || (Date.now = function() { return +new Date(); }); Ext.ticks = (global.performance && global.performance.now) ? function() { return performance.now(); } : Ext.now; Ext._startTime = Ext.ticks(); emptyFn.$nullFn = identityFn.$nullFn = emptyFn.$emptyFn = identityFn.$identityFn = privateFn.$nullFn = true; privateFn.$privacy = 'framework'; emptyFn.$noClearOnDestroy = identityFn.$noClearOnDestroy = true; privateFn.$noClearOnDestroy = true; Ext['suspendLayouts'] = Ext['resumeLayouts'] = emptyFn; for (i in { toString: 1 }) { enumerables = null; } Ext.enumerables = enumerables; Ext.apply = function(object, config, defaults) { if (object) { if (defaults) { Ext.apply(object, defaults); } if (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; }; function addInstanceOverrides(target, owner, overrides) { var name, value; 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; } } } Ext.buildSettings = Ext.apply({ baseCSSPrefix: 'x-' }, Ext.buildSettings || {}); Ext.apply(Ext, { idSeed: 0, idPrefix: 'ext-', isRobot: false, isSecure: /^https/i.test(window.location.protocol), enableGarbageCollector: false, enableListenerCollection: true, name: Ext.sandboxName || 'Ext', privateFn: privateFn, emptyFn: emptyFn, identityFn: identityFn, frameStartTime: Ext.now(), manifest: manifest, debugConfig: Ext.debugConfig || manifest.debug || { hooks: { '*': true } }, enableAria: true, startsWithHashRe: /^#/, 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.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(), emptyArray: Object.freeze ? Object.freeze([]) : [], baseCSSPrefix: Ext.buildSettings.baseCSSPrefix, $eventNameMap: {}, $vendorEventRe: /^(DOMMouse|Moz.+|MS.+|webkit.+)/, canonicalEventName: function(name) { return Ext.$eventNameMap[name] || (Ext.$eventNameMap[name] = (Ext.$vendorEventRe.test(name) ? name : name.toLowerCase())); }, applyIf: function(object, config) { if (object && config && typeof config === 'object') { for (var property in config) { if (object[property] === undefined) { object[property] = config[property]; } } } return object; }, 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.destroyed) { 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, privates; if (owner && owner.$isClass) { privates = overrides.privates; if (privates) { overrides = Ext.apply({}, overrides); delete overrides.privates; addInstanceOverrides(target, owner, privates); } addInstanceOverrides(target, owner, overrides); } 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(obj) { return toString.call(obj) === '[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 && 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, cloneDom) { if (item == null) { return item; } if (cloneDom !== false && 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], cloneDom); } } else if (type === '[object Object]' && item.constructor === Object) { clone = {}; for (key in item) { clone[key] = Ext.clone(item[key], cloneDom); } 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 }, ariaWarn: function(target, msg) { if (Ext.enableAria && !Ext.slicer) { if (!Ext.ariaWarn.first) { Ext.ariaWarn.first = true; Ext.log.warn("WAI-ARIA compatibility warnings can be suppressed " + "by adding the following to application startup code:"); Ext.log.warn(" Ext.ariaWarn = Ext.emptyFn;"); } Ext.log.warn({ msg: msg, dump: target }); } }, 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; }; })(), doElevate: function() { var fn = elevateFn, args = elevateArgs, scope = elevateScope; elevateFn = elevateArgs = elevateScope = null; elevateRet = args ? fn.apply(scope, args) : fn.call(scope); Ext.fireIdle(); }, elevate: function(fn, scope, args, timer) { var ret; if (args && !args.length) { args = null; } Ext._suppressIdle = false; if (timer) { timer.tick(); } if (Ext.elevateFunction) { elevateFn = fn; elevateScope = scope; elevateArgs = args; Ext.elevateFunction(Ext.doElevate); ret = elevateRet; elevateRet = null; } else { ret = args ? fn.apply(scope, args) : fn.call(scope); Ext.fireIdle(); } if (timer) { timer.tock(); } return ret; }, Timer: { all: {}, track: false, captureStack: true, created: function(kind, id, info) { if (!Ext.Timer.track) { return null; } var timer = Ext.apply({ kind: kind, id: id, done: false, firing: false, creator: Ext.Timer.captureStack ? new Error().stack : null, tick: Ext.Timer.tick, tock: Ext.Timer.tock }, info); var timers = Ext.Timer.all[kind] || (Ext.Timer.all[kind] = {}); timers[timer.id] = timer; if (Ext.Timer.hook) { Ext.Timer.hook(timer); } return timer; }, get: function(id, kind) { kind = kind || 'timeout'; var timers = Ext.Timer.all[kind]; return timers && timers[id] || null; }, cancel: function(kind, id) { var timers = Ext.Timer.all[kind]; var timer = timers && timers[id]; if (timer) { timer.cancelled = true; delete timers[id]; } }, tick: function() { if (Ext.Timer.firing) { Ext.log.error('Previous timer state not cleaned up properly: ' + Ext.Timer.firing.creator); } if (this.kind !== 'interval') { this.done = true; delete Ext.Timer.all[this.kind][this.id]; } this.firing = true; Ext.Timer.firing = this; }, tock: function() { this.firing = false; if (Ext.Timer.firing === this) { Ext.Timer.firing = null; } } }, getExpando: function(target, id) { var expandos = target.$expandos; return expandos && expandos[id] || null; }, setExpando: function(target, id, value) { var expandos = target.$expandos; if (value !== undefined) { (expandos || (target.$expandos = {}))[id] = value; } else if (expandos) { delete expandos[id]; } } }); 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 === Ext.raise) { method = method.caller; } 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.raise('The method "' + fail.$owner.$className + '.' + fail.$name + '" has been removed. ' + suggestion); } return fail; return Ext.emptyFn; }; Ext.raise = function() { Ext.Error.raise.apply(Ext.Error, arguments); }; (function(skipNotify) { if (skipNotify || 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; } }; notify.$skipTimerCheck = true; setInterval(notify, 1000); }(!!window.__UNIT_TESTING__)); 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 len = arguments.length, pos = fixArrayIndex(array, index), removed; if (len < 3) { removeCount = array.length - pos; } removed = array.slice(index, fixArrayIndex(array, pos + removeCount)); if (len < 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; }, findInsertionIndex: function(item, items, comparatorFn, index) { var len = items.length, beforeCheck, afterCheck; comparatorFn = comparatorFn || ExtArray.lexicalCompare; if (index < len) { beforeCheck = index > 0 ? comparatorFn(items[index - 1], item) : 0; afterCheck = index < len - 1 ? comparatorFn(item, items[index]) : 0; if (beforeCheck < 1 && afterCheck < 1) { return index; } } return ExtArray.binarySearch(items, item, comparatorFn); }, forEach: ('forEach' in arrayPrototype) ? function(array, fn, scope) { 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 array ? arrayPrototype.indexOf.call(array, item, from) : -1; } : function(array, item, from) { var i, length = array ? array.length : 0; 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 len = array.length, results = new Array(len), i; for (i = 0; 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; }, reduce: Array.prototype.reduce ? function(array, reduceFn, initialValue) { if (arguments.length === 3) { return Array.prototype.reduce.call(array, reduceFn, initialValue); } return Array.prototype.reduce.call(array, reduceFn); } : function(array, reduceFn, initialValue) { array = Object(array); if (!Ext.isFunction(reduceFn)) { Ext.raise('Invalid parameter: expected a function.'); } var index = 0, length = array.length >>> 0, reduced = initialValue; if (arguments.length < 3) { while (true) { if (index in array) { reduced = array[index++]; break; } if (++index >= length) { throw new TypeError('Reduce of empty array with no initial value'); } } } for (; index < length; ++index) { if (index in array) { reduced = reduceFn(reduced, array[index], index, array); } } return reduced; }, 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(strings, getKey, scope) { if (!strings) { return null; } var map = {}, i = strings.length; if (typeof strings === 'string') { map[strings] = 1; } else if (!getKey) { while (i--) { map[strings[i]] = i + 1; } } else if (typeof getKey === 'string') { while (i--) { map[strings[i][getKey]] = i + 1; } } else { while (i--) { map[getKey.call(scope, strings[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); }, move: function(array, fromIdx, toIdx) { if (toIdx === fromIdx) { return; } var item = array[fromIdx], incr = toIdx > fromIdx ? 1 : -1, i; for (i = fromIdx; i != toIdx; i += incr) { array[i] = array[i + incr]; } array[toIdx] = item; }, replace: replace, splice: splice, push: function(target) { var args = arguments, len = args.length, i, newItem; if (target === undefined) { target = []; } else if (!Ext.isArray(target)) { target = [ target ]; } for (i = 1; i < len; i++) { newItem = args[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.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.raise('Expected a falsey value for ' + property + ' but was ' + b); } }, truthy: function(b, msg) { if (!b) { Ext.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.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.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.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.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.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; }, fromCharCode = String.fromCharCode, ExtString; return ExtString = { fromCodePoint: String.fromCodePoint || function() { var codePoint, result = '', codeUnits = [], index = -1, length = arguments.length; while (++index < length) { codePoint = Number(arguments[index]); if (!isFinite(codePoint) || codePoint < 0 || codePoint > 1114111 || Math.floor(codePoint) !== codePoint) { Ext.raise('Invalid code point: ' + codePoint); } if (codePoint <= 65535) { codeUnits.push(codePoint); } else { codePoint -= 65536; codeUnits.push((codePoint >> 10) + 55296, (codePoint % 1024) + 56320); } if (index + 1 === length) { result += fromCharCode(codeUnits); codeUnits.length = 0; } } return result; }, 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, monthInfo = { F: true, m: true, M: true, n: true }, yearInfo = { o: true, Y: true, y: true }, 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]; }); } 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", DAYS_IN_WEEK: 7, MONTHS_IN_YEAR: 12, MAX_DAYS_IN_MONTH: 31, SUNDAY: 0, MONDAY: 1, TUESDAY: 2, WEDNESDAY: 3, THURSDAY: 4, FRIDAY: 5, SATURDAY: 6, 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', defaultTimeFormat: 'h:i A', firstDayOfWeek: 0, weekendDays: [ 0, 6 ], 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, '')); }, isMonthFormat: function(format) { return !!monthInfo[format]; }, isYearFormat: function(format) { return !!yearInfo[format]; }, 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(year, month, day, hour, minute, second, millisecond) { hour = hour || 0; minute = minute || 0; second = second || 0; millisecond = millisecond || 0; var dt = utilDate.add(new nativeDate(year < 100 ? 100 : year, month - 1, day, hour, minute, second, millisecond), utilDate.YEAR, year < 100 ? year - 100 : 0); return year === dt.getFullYear() && month === dt.getMonth() + 1 && day === dt.getDate() && hour === dt.getHours() && minute === dt.getMinutes() && second === dt.getSeconds() && millisecond === 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]|[1-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 (isNaN(date.getTime())) { return date; } 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, preventDstAdjust) { var d = utilDate.clone(date), base = 0, day, decimalValue; if (!interval || value === 0) { return d; } decimalValue = value - parseInt(value, 10); value = parseInt(value, 10); if (value) { switch (interval.toLowerCase()) { case utilDate.MILLI: if (preventDstAdjust) { d.setMilliseconds(d.getMilliseconds() + value); } else { d.setTime(d.getTime() + value); }; break; case utilDate.SECOND: if (preventDstAdjust) { d.setSeconds(d.getSeconds() + value); } else { d.setTime(d.getTime() + value * 1000); }; break; case utilDate.MINUTE: if (preventDstAdjust) { d.setMinutes(d.getMinutes() + value); } else { d.setTime(d.getTime() + value * 60 * 1000); }; break; case utilDate.HOUR: if (preventDstAdjust) { d.setHours(d.getHours() + value); } else { d.setTime(d.getTime() + value * 60 * 60 * 1000); }; break; case utilDate.DAY: if (preventDstAdjust) { d.setDate(d.getDate() + value); } else { d.setTime(d.getTime() + value * 24 * 60 * 60 * 1000); }; 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, preventDstAdjust) { return utilDate.add(date, interval, -value, preventDstAdjust); }, between: function(date, start, end) { var t = date.getTime(); return start.getTime() <= t && t <= end.getTime(); }, isWeekend: function(date) { return Ext.Array.indexOf(this.weekendDays, date.getDay()) > -1; }, utcToLocal: function(d) { return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds()); }, localToUtc: function(d) { return utilDate.utc(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()); }, utc: function(year, month, day, hour, min, s, ms) { return new Date(Date.UTC(year, month, day, hour || 0, min || 0, s || 0, ms || 0)); }, 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; } } }; utilDate.parseCodes.C = utilDate.parseCodes.c; return utilDate; }()); Ext.Function = (function() { var lastTime = 0, animFrameId, animFrameHandlers = [], animFrameNoArgs = [], idSource = 0, animFrameMap = {}, slice = Array.prototype.slice, win = window, global = Ext.global, hasImmediate = !Ext.disableImmediate && !!(global.setImmediate && global.clearImmediate), requestAnimFrame = win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || function(callback) { var currTime = Ext.now(), timeToCall = Math.max(0, 16 - (currTime - lastTime)), timerFn = function() { callback(currTime + timeToCall); }, id; timerFn.$origFn = callback.$origFn || callback; timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck; id = win.setTimeout(timerFn, timeToCall); lastTime = currTime + timeToCall; return id; }, fireHandlers = function() { var len = animFrameHandlers.length, id, i, handler; animFrameId = null; var timer; for (i = 0; i < len; i++) { handler = animFrameHandlers[i]; id = handler[3]; if (animFrameMap[id]) { delete animFrameMap[id]; timer = Ext.Timer.get(id, 'raf'); if (timer) { timer.tick(); } handler[0].apply(handler[1] || global, handler[2] || animFrameNoArgs); if (timer) { timer.tock(); } } } animFrameHandlers = animFrameHandlers.slice(len); }, fireElevatedHandlers = function() { Ext.elevate(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 fn.bind(scope); } var method = fn; 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 || global, callArgs); }; }, bindCallback: function(callback, scope, args, delay, caller) { return function() { var a = slice.call(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) { var newMethod, prop; newMethod = function() { return method.apply(this, arguments); }; for (prop in method) { if (method.hasOwnProperty(prop)) { newMethod[prop] = method[prop]; } } return newMethod; }, 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; return (newFn.apply(scope || me || global, args) !== false) ? origFn.apply(me || global, args) : returnValue; }; } }, createDelayed: function(fn, delay, scope, args, appendArgs) { var boundFn = fn; if (scope || args) { boundFn = Ext.Function.bind(fn, scope, args, appendArgs); } return function() { var me = this, args = slice.call(arguments), timerFn, timerId; var timer; timerFn = function() { Ext.elevate(boundFn, me, args, timer); }; timerId = setTimeout(timerFn, delay); timerFn.$origFn = fn.$origFn || fn; timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck; timer = Ext.Timer.created('timeout', timerId, { type: 'createDelayed', fn: fn, timerFn: timerFn }); }; }, defer: function(fn, millis, scope, args, appendArgs) { var timerId = 0, timerFn, boundFn; var timer; if (!scope && !args && !appendArgs) { boundFn = fn; } else { boundFn = Ext.Function.bind(fn, scope, args, appendArgs); } if (millis > 0) { timerFn = function() { Ext.elevate(boundFn, null, null, timer); }; timerId = setTimeout(timerFn, millis); timerFn.$origFn = fn.$origFn || fn; timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck; timer = Ext.Timer.created('timeout', timerId, { type: 'defer', fn: fn, timerFn: timerFn }); } else { boundFn(); } return timerId; }, interval: function(fn, millis, scope, args, appendArgs) { var timerFn, timerId, boundFn; var timer; boundFn = Ext.Function.bind(fn, scope, args, appendArgs); timerFn = function() { Ext.elevate(boundFn, null, null, timer); }; timerId = setInterval(timerFn, millis); timerFn.$origFn = boundFn.$origFn || fn; timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck; timer = Ext.Timer.created('interval', timerId, { type: 'interval', fn: fn, timerFn: timerFn }); return timerId; }, 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, result = function() { var callArgs = args || slice.call(arguments, 0), me = scope || this, timerFn; var timer; if (timerId) { Ext.undefer(timerId); } timerFn = function() { Ext.elevate(fn, me, callArgs, timer); }; result.timer = timerId = setTimeout(timerFn, buffer); timerFn.$origFn = fn.$origFn || fn; timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck; timer = Ext.Timer.created('timeout', timerId, { type: 'createBuffered', fn: fn, timerFn: timerFn }); }; return result; }, createAnimationFrame: function(fn, scope, args, queueStrategy) { var boundFn, timerId; queueStrategy = queueStrategy || 3; boundFn = function() { var timerFn, callArgs = args || slice.call(arguments, 0); scope = scope || this; if (queueStrategy === 3 && timerId) { ExtFunction.cancelAnimationFrame(timerId); } if ((queueStrategy & 1) || !timerId) { timerFn = function() { timerId = boundFn.timerId = null; fn.apply(scope, callArgs); }; timerFn.$origFn = fn.$origFn || fn; timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck; timerId = boundFn.timerId = ExtFunction.requestAnimationFrame(timerFn); } }; return boundFn; }, requestAnimationFrame: function(fn, scope, args) { var id = ++idSource, handler = slice.call(arguments, 0); handler[3] = id; animFrameMap[id] = 1; Ext.Timer.created('raf', id, { type: 'raf', fn: fn }); animFrameHandlers.push(handler); if (!animFrameId) { animFrameId = requestAnimFrame(fireElevatedHandlers); } return id; }, cancelAnimationFrame: function(id) { delete animFrameMap[id]; Ext.Timer.cancel('raf', id); }, createThrottled: function(fn, interval, scope) { var lastCallTime = 0, elapsed, lastArgs, timerId, execute = function() { fn.apply(scope, lastArgs); lastCallTime = Ext.now(); lastArgs = timerId = null; }; execute.$origFn = fn.$origFn || fn; execute.$skipTimerCheck = execute.$origFn.$skipTimerCheck; return function() { if (!scope) { scope = this; } elapsed = Ext.now() - lastCallTime; lastArgs = Ext.Array.slice(arguments); if (elapsed >= interval) { Ext.undefer(timerId); execute(); } else if (!timerId) { timerId = Ext.defer(execute, interval - elapsed); } }; }, createBarrier: function(count, fn, scope) { var barrierFn = function() { if (!--count) { fn.apply(scope, arguments); } }; barrierFn.$origFn = fn.$origFn || fn; barrierFn.$skipTimerCheck = barrierFn.$origFn.$skipTimerCheck; return barrierFn; }, 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); }); }, interceptAfterOnce: function(object, methodName, fn, scope) { var origMethod = object[methodName], newMethod; newMethod = function() { var ret; if (origMethod) { origMethod.apply(this, arguments); } ret = fn.apply(scope || this, arguments); object[methodName] = origMethod; object = methodName = fn = scope = origMethod = newMethod = null; return ret; }; object[methodName] = newMethod; return newMethod; }, makeCallback: function(callback, scope) { if (!scope[callback]) { if (scope.$className) { Ext.raise('No method "' + callback + '" on ' + scope.$className); } Ext.raise('No method "' + callback + '"'); } return function() { return scope[callback].apply(scope, arguments); }; }, memoize: function(fn, scope, hashFn) { var memo = {}, isFunc = hashFn && Ext.isFunction(hashFn); return function(value) { var key = isFunc ? hashFn.apply(scope, arguments) : value; if (!(key in memo)) { memo[key] = fn.apply(scope, arguments); } return memo[key]; }; }, _stripCommentRe: /(\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/)|(\/\/.*)/g, toCode: function(fn) { var s = fn ? fn.toString() : ''; s = s.replace(ExtFunction._stripCommentRe, ''); return s; }, fireElevatedHandlers: function() { fireElevatedHandlers(); } }; Ext.asap = hasImmediate ? function(fn, scope, parameters) { var boundFn = fn, timerFn, timerId; var timer; if (scope != null || parameters != null) { boundFn = ExtFunction.bind(fn, scope, parameters); } timerFn = function() { Ext.elevate(boundFn, null, null, timer); }; timerId = setImmediate(timerFn); timerFn.$origFn = fn.$origFn || fn; timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck; timer = Ext.Timer.created('asap', timerId, { type: 'asap', fn: fn, timerFn: timerFn }); return timerId; } : function(fn, scope, parameters) { var boundFn = fn, timerFn, timerId; var timer; if (scope != null || parameters != null) { boundFn = ExtFunction.bind(fn, scope, parameters); } timerFn = function() { Ext.elevate(boundFn, null, null, timer); }; timerId = setTimeout(timerFn, 0, true); timerFn.$origFn = fn.$origFn || fn; timerFn.$skipTimerCheck = timerFn.$origFn.$skipTimerCheck; timer = Ext.Timer.created('timeout', timerId, { type: 'asap', fn: fn, timerFn: timerFn }); return timerId; }; Ext.unasap = hasImmediate ? function(id) { if (id) { clearImmediate(id); Ext.Timer.cancel('asap', id); } return null; } : function(id) { return Ext.undefer(id); }; Ext.asapCancel = function(id) { return Ext.unasap(id); }; Ext.defer = ExtFunction.defer; Ext.undefer = function(id) { if (id) { clearTimeout(id); Ext.Timer.cancel('timeout', id); } return null; }; Ext.interval = ExtFunction.interval; Ext.uninterval = function(id) { if (id) { clearInterval(id); Ext.Timer.cancel('interval', id); } return null; }; Ext.pass = ExtFunction.pass; Ext.bind = ExtFunction.bind; Ext.raf = function() { return ExtFunction.requestAnimationFrame.apply(ExtFunction, arguments); }; Ext.unraf = function(id) { ExtFunction.cancelAnimationFrame(id); }; return ExtFunction; })(); Ext.Number = (new function() { var ExtNumber = this, isToFixedBroken = (0.9).toFixed() !== '1', math = Math, ClipDefault = { count: false, inclusive: false, wrap: true }; Number.MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER || -(math.pow(2, 53) - 1); Number.MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || math.pow(2, 53) - 1; Ext.apply(ExtNumber, { MIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER, MAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER, floatRe: /^[-+]?(?:\d+|\d*\.\d*)(?:[Ee][+-]?\d+)?$/, intRe: /^[-+]?\d+(?:[Ee]\+?\d+)?$/, Clip: { DEFAULT: ClipDefault, COUNT: Ext.applyIf({ count: true }, ClipDefault), INCLUSIVE: Ext.applyIf({ inclusive: true }, ClipDefault), NOWRAP: Ext.applyIf({ wrap: false }, ClipDefault) }, parseFloat: function(value) { if (value === undefined) { value = null; } if (value !== null && typeof value !== 'number') { value = String(value); value = ExtNumber.floatRe.test(value) ? +value : null; if (isNaN(value)) { value = null; } } return value; }, parseInt: function(value) { if (value === undefined) { value = null; } if (typeof value === 'number') { value = Math.floor(value); } else if (value !== null) { value = String(value); value = ExtNumber.intRe.test(value) ? +value : null; } return value; }, binarySearch: function(array, value, begin, end) { if (begin === undefined) { begin = 0; } if (end === undefined) { end = array.length; } --end; var middle, midVal; while (begin <= end) { middle = (begin + end) >>> 1; midVal = array[middle]; if (value === midVal) { return middle; } if (midVal < value) { begin = middle + 1; } else { end = middle - 1; } } return begin; }, bisectTuples: function(array, value, index, begin, end) { if (begin === undefined) { begin = 0; } if (end === undefined) { end = array.length; } --end; var middle, midVal; while (begin <= end) { middle = (begin + end) >>> 1; midVal = array[middle][index]; if (value === midVal) { return middle; } if (midVal < value) { begin = middle + 1; } else { end = middle - 1; } } return begin; }, 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; }, roundToNearest: function(value, interval) { interval = interval || 1; return interval * math.round(value / interval); }, roundToPrecision: function(value, precision) { var factor = math.pow(10, precision || 1); return math.round(value * factor) / factor; }, truncateToPrecision: function(value, precision) { var factor = math.pow(10, precision || 1); return parseInt(value * factor, 10) / factor; }, sign: math.sign || function(x) { x = +x; if (x === 0 || isNaN(x)) { return x; } return (x > 0) ? 1 : -1; }, log10: math.log10 || function(x) { return math.log(x) * math.LOG10E; }, isEqual: function(n1, n2, epsilon) { if (!(typeof n1 === 'number' && typeof n2 === 'number' && typeof epsilon === 'number')) { Ext.raise("All parameters should be valid numbers."); } return math.abs(n1 - n2) < epsilon; }, isFinite: Number.isFinite || function(value) { return typeof value === 'number' && isFinite(value); }, isInteger: Number.isInteger || function(value) { return ~~(value + 0) === value; }, 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, args = arguments, ln = args.length, mergeFn = ExtObject.merge, cloneFn = Ext.clone, object, key, value, sourceKey; for (; i < ln; i++) { object = args[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 }, owner: { isOwner: 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 (callback[2] === '.') { if (callback.substr(0, 2) !== 'up') { Ext.raise('Invalid callback method name "' + callback + '"'); } if (scope) { Ext.raise('Callback "up" syntax is incompatible with scopes'); } if (!caller || !Ext.isFunction(caller.up)) { Ext.raise('Callback "up" syntax requires a caller with "up" method'); } callback = callback.substr(3); for (scope = caller.up(); scope && !scope[callback]; scope = scope.up()) {} if (!scope || !Ext.isFunction(scope[callback])) { Ext.raise('No such method "' + callback + '" found up() from ' + scope.getId ? scope.getId() : scope.id); } } else if ((!scope || namedScope) && caller) { scope = caller.resolveListenerScope(namedScope ? scope : defaultScope); } if (!scope || !Ext.isObject(scope)) { Ext.raise('Named method "' + callback + '" requires a scope object'); } if (!Ext.isFunction(scope[callback])) { Ext.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 { ret = args ? callback.apply(scope, args) : 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' || from === '0') ? false : Boolean(from); case 'null': return isString && (!from || from === 'null') ? null : false; case 'undefined': return isString && (!from || from === 'undefined') ? undefined : false; 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; }, copy: 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 (source.hasOwnProperty(name) || (usePrototypeKeys && name in source)) { 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; }, copyIf: 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 (!(name in destination) && (name in source)) { destination[name] = source[name]; } } return destination; }, extend: (function() { var objectConstructor = Object.prototype.constructor, inlineOverrides = function(o) { var m; for (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.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; }; }()), isOnline: function() { return Ext.global.navigator.onLine; }, 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); } }, _resourcePoolRe: /^[<]([^<>@:]*)(?:[@]([^<>@:]+))?[>](.+)$/, resolveResource: function(url) { var ret = url, m; if (url && url.charAt(0) === '<') { m = Ext._resourcePoolRe.exec(url); if (m) { ret = Ext.getResourcePath(m[3], m[1], m[2]); } } return ret; }, 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.raise("getScrollbarSize called before DomReady"); } var scrollbarSize = Ext._scrollbarSize; if (force || !scrollbarSize) { var db = document.body, div = document.createElement('div'), h, w; div.style.width = div.style.height = '100px'; div.style.overflow = 'scroll'; div.style.position = 'absolute'; db.appendChild(div); Ext._scrollbarSize = scrollbarSize = { width: w = div.offsetWidth - div.clientWidth, height: h = div.offsetHeight - div.clientHeight }; scrollbarSize.reservedWidth = w ? 'calc(100% - ' + w + 'px)' : ''; scrollbarSize.reservedHeight = h ? 'calc(100% - ' + h + 'px)' : ''; 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.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) { if (!instance && !classReference) { Ext.raise('[Ext.factory] Cannot determine type of class to create'); } return instance || Ext.create(classReference); } if (!Ext.isObject(config)) { Ext.raise("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); }, convertKeyedItems: function(items, defaultProperty, functionProperty) { if (items && !items.isInstance && Ext.isObject(items)) { var obj = items, item, itemId, value; items = []; if (obj.xtype || obj.xclass || obj.itemId || obj.id) { items.push(obj); } else { for (itemId in obj) { item = obj[itemId]; if (item) { if (item === true) { item = {}; } else if (typeof item === 'function') { if (!functionProperty) { Ext.raise('Function not expected here'); } value = item; item = {}; item[functionProperty] = value; } else if (typeof item === 'string') { value = item; item = {}; item[defaultProperty || 'xtype'] = value; } else { item = Ext.apply({}, item); } item.itemId = itemId; items.push(item); } } } } return items; }, weightSortFn: function(lhs, rhs) { return (lhs.weight || 0) - (rhs.weight || 0); }, concat: function(a, b) { var noB = b == null, E = Ext.emptyArray; return (a == null) ? (noB ? a : E.concat(b)) : (noB ? E.concat(a) : E.concat(a, b)); }, 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 = dumpObject(value, level + 1, maxLevel, withFunctions); } else if (Ext.isObject(value)) { member = 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, toolkitNames = { classic: 1, modern: 1 }, 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: 'core', touch: 'modern' }, to: { ext: [ 'extjs' ], 'core': [ 'core' ], modern: [ 'touch' ] } }, 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) { if (packageName in toolkitNames) { Ext.toolkit = packageName; } 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]; if (pkg && pkg.version) { 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', '6.6.0.258'); Ext.setVersion('core', '6.6.0.258'); } })(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, 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()); }, getEventedSetter: function() { return this.eventedSetter || (this.root.eventedSetter = this.makeEventedSetter()); }, 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; }, makeEventedSetter: function() { var name = this.name, names = this.names, prefixedName = names.internal, getName = names.get, applyName = names.apply, updateName = names.update, changeEventName = names.changeEvent, updateFn = function(me, value, oldValue, internalName) { me[internalName] = value; if (me[updateName]) { me[updateName](value, oldValue); } }, 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])) { if (me.isConfiguring) { me[internalName] = value; if (me[updateName]) { me[updateName](value, oldValue); } } else { me.fireEventedAction(changeEventName, [ me, value, oldValue ], updateFn, me, [ me, value, oldValue, internalName ]); } } } 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, superCfg = cls.superclass ? cls.superclass.self.$config : null; me.cls = cls; me.superCfg = superCfg; if (superCfg) { me.configs = ExtObject.chain(superCfg.configs); me.cachedConfigs = ExtObject.chain(superCfg.cachedConfigs); me.initMap = ExtObject.chain(superCfg.initMap); me.values = ExtObject.chain(superCfg.values); me.needsFork = superCfg.needsFork; me.deprecations = ExtObject.chain(superCfg.deprecations); } else { me.configs = {}; me.cachedConfigs = {}; me.initMap = {}; me.values = {}; me.deprecations = {}; } 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; isCached = false; 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.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.getter || cfg.getGetter(); } if (!prototype[s = names.set]) { prototype[s] = (meta && meta.evented) ? (cfg.eventedSetter || cfg.getEventedSetter()) : (cfg.setter || 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; } }, addDeprecations: function(configs) { var me = this, deprecations = me.deprecations, className = (me.cls.$className || '') + '#', message, newName, oldName; for (oldName in configs) { newName = configs[oldName]; if (!newName) { message = 'This config has been removed.'; } else if (!(message = newName.message)) { message = 'This config has been renamed to "' + newName + '"'; } deprecations[oldName] = className + oldName + ': ' + message; } }, configure: function(instance, instanceConfig) { var me = this, configs = me.configs, deprecations = me.deprecations, initMap = me.initMap, initListMap = me.initListMap, initList = me.initList, prototype = me.cls.prototype, values = me.values, remaining = 0, firstInstance = !initList, cachedInitList, cfg, getter, i, internalName, ln, names, name, value, isCached, valuesKey, field; values = me.needsFork ? ExtObject.fork(values) : ExtObject.chain(values); instance.isConfiguring = true; if (firstInstance) { me.initList = initList = []; me.initListMap = initListMap = {}; instance.isFirstInstance = true; for (name in initMap) { cfg = configs[name]; isCached = cfg.cached; if (initMap[name]) { 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.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 (deprecations[name]) { Ext.log.warn(deprecations[name]); if (!cfg) { continue; } } if (!cfg) { field = instance.self.prototype[name]; if (instance.$configStrict && (typeof field === 'function') && !field.$nullFn) { Ext.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, false); } } } 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, false); } } } baseConfig[name] = value; } return baseConfig; }, reconfigure: function(instance, instanceConfig, options) { var currentConfig = instance.config, configList = [], strict = instance.$configStrict && !(options && options.strict === false), configs = this.configs, defaults = options && options.defaults, cfg, getter, i, len, name, names, prop; for (name in instanceConfig) { cfg = configs[name]; if (defaults && instance.hasOwnProperty(cfg && instance.$configPrefixed ? cfg.names.internal : name)) { continue; } currentConfig[name] = instanceConfig[name]; if (this.deprecations[name]) { Ext.log.warn(this.deprecations[name]); if (!cfg) { continue; } } if (cfg) { instance[cfg.names.get] = cfg.initGetter || cfg.getInitGetter(); } else { prop = instance.self.prototype[name]; if (strict) { if ((typeof prop === 'function') && !prop.$nullFn) { Ext.Error.raise("Cannot override method " + name + " on " + instance.$className + " instance."); continue; } else { if (name !== 'type') { Ext.log.warn('No such config "' + name + '" for class ' + instance.$className); } } } } 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 { instance[name] = instanceConfig[name]; } } } }, 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 = [], 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.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.raise(message); }, set: function(value) { Ext.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, Reaper; Ext.Reaper = Reaper = { delay: 100, queue: [], timer: null, add: function(obj) { if (!Reaper.timer) { Reaper.timer = Ext.defer(Reaper.tick, Reaper.delay); } Reaper.queue.push(obj); }, flush: function() { if (Reaper.timer) { Ext.undefer(Reaper.timer); Reaper.timer = null; } var queue = Reaper.queue, n = queue.length, i, obj; Reaper.queue = []; for (i = 0; i < n; ++i) { obj = queue[i]; if (obj && obj.$reap) { obj.$reap(); } } }, tick: function() { Reaper.timer = null; Reaper.flush(); } }; 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), configurator = me.getConfigurator(), 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.configs; if (names) { configurator.addDeprecations(names); } 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(parentClass) { var me = this, parentPrototype = parentClass.prototype, prototype, name, statics; prototype = me.prototype = Ext.Object.chain(parentPrototype); prototype.self = me; me.superclass = prototype.superclass = parentPrototype; if (!parentClass.$isClass) { for (name in BasePrototype) { if (name in prototype) { prototype[name] = BasePrototype[name]; } } } statics = parentPrototype.$inheritableStatics; if (statics) { for (name in statics) { if (!me.hasOwnProperty(name)) { me[name] = parentClass[name]; } } } if (parentClass.$onExtended) { me.$onExtended = parentClass.$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 me = this, proto = me.prototype, inheritableStatics = me.$inheritableStatics, name, member, current; if (!inheritableStatics) { inheritableStatics = Ext.apply({}, proto.$inheritableStatics); me.$inheritableStatics = proto.$inheritableStatics = inheritableStatics; } var className = Ext.getClassName(me) + '.'; for (name in members) { if (members.hasOwnProperty(name)) { member = members[name]; current = me[name]; if (typeof member == 'function') { member.name = className + name; } if (typeof current === 'function' && !current.$isClass && !current.$nullFn) { member.$previous = current; } me[name] = member; inheritableStatics[name] = true; } } return me; }, 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.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 (members.platformConfig) { me.addPlatformConfig(members); } 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; }, addPlatformConfig: function(data) { var me = this, prototype = me.prototype, platformConfigs = data.platformConfig, added, classConfigs, configs, configurator, keys, name, value, i, ln; delete prototype.platformConfig; if (platformConfigs instanceof Array) { throw new Error('platformConfigs must be specified as an object.'); } configurator = me.getConfigurator(); classConfigs = configurator.configs; keys = Ext.getPlatformConfigKeys(platformConfigs); for (i = 0 , ln = keys.length; i < ln; ++i) { configs = platformConfigs[keys[i]]; added = null; for (name in configs) { value = configs[name]; if (name in classConfigs) { (added || (added = {}))[name] = value; } else { prototype[name] = value; } } if (added) { configurator.add(added); } } }, 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, mixinName, mixinValue, mixins, mixinStatics, staticName; 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 (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' || key === '$inheritableStatics') && (prototype[key] === undefined)) { prototype[key] = mixinValue; } } statics = mixin.$inheritableStatics; if (statics) { mixinStatics = {}; for (staticName in statics) { if (!me.hasOwnProperty(staticName)) { mixinStatics[staticName] = mixinClass[staticName]; } } me.addInheritableStatics(mixinStatics); } 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, destroyed: false, clearPropertiesOnDestroy: true, clearPrototypeOnDestroy: 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; }, initConfig: function(instanceConfig) { var me = this, cfg = me.self.getConfigurator(); me.initConfig = Ext.emptyFn; me.initialConfig = instanceConfig || {}; cfg.configure(me, instanceConfig); return me; }, beforeInitConfig: Ext.emptyFn, getConfig: function(name, peek, ifInitialized) { var me = this, ret, cfg, propName; if (name) { cfg = me.self.$config.configs[name]; if (cfg) { propName = me.$configPrefixed ? cfg.names.internal : name; if (ifInitialized) { ret = me.hasOwnProperty(propName) ? me[propName] : null; } else if (peek) { ret = me.hasOwnProperty(propName) ? me[propName] : me.config[name]; } else { ret = me[cfg.names.get](); } } else { ret = me[name]; } } else { ret = me.getCurrentConfig(); } return ret; }, destroyMembers: function() { var me = this, configs = me.self.$config.configs, len = arguments.length, cfg, name, value, i; for (i = 0; i < len; i++) { name = arguments[i]; cfg = configs[name]; name = cfg && me.$configPrefixed ? cfg.names.internal : name; value = me.hasOwnProperty(name) && me[name]; if (value) { Ext.destroy(value); me[name] = null; } } }, freezeConfig: function(name) { var me = this, config = Ext.Config.get(name), names = config.names, value = me[names.get](); me[names.set] = function(v) { if (v !== value) { Ext.raise('Cannot change frozen config "' + name + '"'); } return me; }; if (!Ext.isIE8) { Object.defineProperty(me, me.$configPrefixed ? names.internal : name, { get: function() { return value; }, set: function(v) { if (v !== value) { Ext.raise('Cannot change frozen config "' + name + '"'); } } }); } }, setConfig: function(name, value, options) { var me = this, configurator, config, prop; if (name) { configurator = me.self.getConfigurator(); if (typeof name === 'string') { config = configurator.configs[name]; if (!config) { if (me.$configStrict) { prop = me.self.prototype[name]; if ((typeof prop === 'function') && !prop.$nullFn) { Ext.Error.raise("Cannot override method " + name + " on " + me.$className + " instance."); return me; } else { if (name !== 'type') { Ext.log.warn('No such config "' + name + '" for class ' + me.$className); } } } config = Ext.Config.map[name] || Ext.Config.get(name); } if (me[config.names.set]) { me[config.names.set](value); } else { me[name] = value; } } else { configurator.reconfigure(me, name, options || value); } } return me; }, getCurrentConfig: function() { var cfg = this.self.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.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.destroyed) { value.destroy(); } else if (value.parentNode && 'nodeType' in value) { value.parentNode.removeChild(value); } } me[link] = null; } return me; }, $reap: function() { var me = this, protectedProps = me.$noClearOnDestroy, props, prop, value, type, i, len; props = Ext.Object.getKeys(me); for (i = 0 , len = props.length; i < len; i++) { prop = props[i]; if (!protectedProps || !protectedProps[prop]) { value = me[prop]; type = typeof value; if (type === 'object' || (type === 'function' && !value.$noClearOnDestroy)) { me[prop] = null; } } } me.$nulled = true; if (Object.setPrototypeOf) { if (me.clearPrototypeOnDestroy && !me.$vetoClearingPrototypeOnDestroy) { props = me.$preservePrototypeProperties; if (props) { for (i = 0 , len = props.length; i < len; i++) { prop = props[i]; if (!me.hasOwnProperty(prop)) { me[prop] = me[prop]; } } } Object.setPrototypeOf(me, null); } } }, destroy: function() { var me = this, links = me.$links, clearPropertiesOnDestroy = me.clearPropertiesOnDestroy; if (links) { me.$links = null; me.unlink(Ext.Object.getKeys(links)); } me.destroy = Ext.emptyFn; me.isDestroyed = me.destroyed = true; if (clearPropertiesOnDestroy === true) { if (!me.isObservable) { me.$reap(); } } else if (clearPropertiesOnDestroy) { if (clearPropertiesOnDestroy !== 'async') { Ext.raise('Invalid value for clearPropertiesOnDestroy'); } Reaper.add(me); } } }); 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.raise(msg); } }; Ext.Reaper.tick.$skipTimerCheck = true; return Base; }(Ext.Function.flexSetter)); (function(LRU, prototype) { (Ext.util || (Ext.util = {})).LRU = LRU = 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; }; LRU.prototype = prototype = { count: 0, add: function(key, value) { var me = this, map = me.map, entry = map[key]; if (entry) { me.unlink(entry); --me.count; } map[key] = entry = { id: ++me.seed, key: key, value: value }; me.link(entry); ++me.count; return entry; }, clear: function(fn, scope) { var me = this, head = me.head, entry = head.next; head.next = head.prev = head; me.count = 0; if (fn && !fn.$nullFn) { for (; entry !== head; entry = entry.next) { fn.call(scope || me, entry.key, entry.value); } } }, 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; } } }, prune: function(fn, scope) { var me = this, entry = me.head.prev, ret; if (me.count) { ret = entry.value; me.unlink(entry); --me.count; if (fn) { fn.call(scope || me, entry.key, ret); } } return ret; }, remove: function(key) { var me = this, map = me.map, entry = map[key], value; if (entry) { me.unlink(entry); value = entry.value; delete map[key]; --me.count; } return value; }, touch: function(key) { var me = this, head = me.head, entry = me.map[key]; if (entry && entry.prev !== head) { me.unlink(entry); me.link(entry); } }, trim: function(size, fn, scope) { while (this.count > size) { this.prune(fn, scope); } }, link: function(entry) { var head = this.head, first = head.next; entry.next = first; entry.prev = head; head.next = entry; first.prev = entry; }, unlink: function(entry) { var next = entry.next, prev = entry.prev; prev.next = next; next.prev = prev; } }; prototype.destroy = function() { this.clear.apply(this, arguments); }; }()); (function(LRU, fn, Cache) { Ext.util.Cache = Cache = function(config) { LRU.call(this, config); }; fn.prototype = LRU.prototype; Cache.prototype = Ext.apply(new fn(), { maxSize: 100, clear: function() { LRU.prototype.clear.call(this, this.evict); }, get: function(key) { var me = this, entry = me.map[key], value; if (entry) { value = entry.value; me.touch(key); } else { value = me.miss.apply(me, arguments); me.add(key, value); me.trim(me.maxSize, me.evict); } return value; }, evict: Ext.emptyFn }); }(Ext.util.LRU, function() {})); (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) { try { return (' + code + '); } catch(e) { return false;}}'); }; 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('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', '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 = {}; me.nameToPrefix = {}; }; Ext.Inventory.prototype = { _array1: [ 0 ], prefixes: null, dotRe: /\./g, wildcardRe: /\*/g, addAlias: function(className, alias, update) { return this.addMapping(className, alias, this.aliasToName, this.nameToAliases, update); }, addAlternate: function(className, alternate) { return this.addMapping(className, alternate, this.alternateToName, this.nameToAlternates); }, addMapping: function(className, alternate, toName, nameTo, update) { 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 (!update && toName[a] && ('Ext.Gadget' !== 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.nameToPrefix[className] || (me.nameToPrefix[className] = 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; } else if (className in this.nameToPrefix) { return this.nameToPrefix[className]; } var prefixes = this.getPrefixes(), length = className.length, items, currChar, currSubstr, prefix, j, jlen; while (length-- > 0) { items = prefixes[length]; if (items) { currChar = className.charAt(length); if (currChar !== '.') { continue; } currSubstr = className.substring(0, length); for (j = 0 , jlen = items.length; j < jlen; j++) { prefix = items[j]; if (prefix === className.substring(0, length)) { return prefix; } } } } return ''; }, getPrefixes: function() { var me = this, prefixes = me.prefixes, names, name, nameLength, items, i, len; if (!prefixes) { names = me.names.slice(0); me.prefixes = prefixes = []; for (i = 0 , len = names.length; i < len; i++) { name = names[i]; nameLength = name.length; items = prefixes[nameLength] || (prefixes[nameLength] = []); items.push(name); } } 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]; delete me.nameToPrefix[name]; if (aliases) { for (i = aliases.length; i--; ) { if (name === aliasToName[a = aliases[i]]) { delete aliasToName[a]; } } } if (alternates) { for (i = alternates.length; i--; ) { if (name === alternateToName[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[0], 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; me.nameToPrefix = {}; return me; }) }; Ext.ClassManager = (function(Class, alias, arraySlice, arrayFrom, global) { var makeCtor = Ext.Class.makeCtor, nameLookupStack = [], namespaceCache = { Ext: { name: 'Ext', value: Ext } }, Manager = Ext.apply(new Ext.Inventory(), { classes: {}, classCount: 0, classState: {}, existCache: {}, instantiators: [], isCreated: function(className) { 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; } if (!Manager.lookupName(className, false)) { return false; } 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); } }, $namespaceCache: namespaceCache, addRootNamespaces: function(namespaces) { for (var name in namespaces) { namespaceCache[name] = { name: name, value: namespaces[name] }; } }, clearNamespaceCache: function() { nameLookupStack.length = 0; for (var name in namespaceCache) { if (!namespaceCache[name].value) { delete namespaceCache[name]; } } }, getNamespaceEntry: function(namespace) { if (typeof namespace !== 'string') { return namespace; } var entry = namespaceCache[namespace], i; if (!entry) { i = namespace.lastIndexOf('.'); if (i < 0) { entry = { name: namespace }; } else { entry = { name: namespace.substring(i + 1), parent: Manager.getNamespaceEntry(namespace.substring(0, i)) }; } namespaceCache[namespace] = entry; } return entry; }, lookupName: function(namespace, autoCreate) { var entry = Manager.getNamespaceEntry(namespace), scope = Ext.global, i = 0, e, parent; for (e = entry; e; e = e.parent) { nameLookupStack[i++] = e; } while (scope && i-- > 0) { e = nameLookupStack[i]; parent = scope; scope = e.value || scope[e.name]; if (!scope && autoCreate) { parent[e.name] = scope = {}; } } return scope; }, setNamespace: function(namespace, value) { var entry = Manager.getNamespaceEntry(namespace), scope = Ext.global; if (entry.parent) { scope = Manager.lookupName(entry.parent, true); } scope[entry.name] = value; return value; }, setXType: function(cls, xtype) { var className = cls.$className, C = className ? cls : Manager.get(className = cls), proto = C.prototype, xtypes = proto.xtypes, xtypesChain = proto.xtypesChain, xtypesMap = proto.xtypesMap; if (!proto.hasOwnProperty('xtypes')) { proto.xtypes = xtypes = []; proto.xtypesChain = xtypesChain = xtypesChain ? xtypesChain.slice(0) : []; proto.xtypesMap = xtypesMap = Ext.apply({}, xtypesMap); } Manager.addAlias(className, 'widget.' + xtype, true); xtypes.push(xtype); xtypesChain.push(xtype); xtypesMap[xtype] = true; }, set: function(name, value) { var targetName = Manager.getName(value); Manager.classes[name] = Manager.setNamespace(name, value); Manager.classCount++; if (targetName && targetName !== name) { Manager.addAlternate(targetName, name); } return Manager; }, get: function(name) { return Manager.classes[name] || Manager.lookupName(name, false); }, addNameAliasMappings: function(aliases) { Manager.addAlias(aliases); }, addNameAlternateMappings: function(alternates) { Manager.addAlternate(alternates); }, getByAlias: function(alias) { return Manager.get(Manager.getNameByAlias(alias)); }, getByConfig: function(config, aliasPrefix) { var xclass = config.xclass, name; if (xclass) { name = xclass; } else { name = config.xtype; if (name) { aliasPrefix = 'widget.'; } else { name = config.type; } name = Manager.getNameByAlias(aliasPrefix + name); } return Manager.get(name); }, 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 = 1, dependenciesLoaded, classReady = function() { var cls, dependencies, i, key, temp; if (!dependenciesLoaded) { 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); } } } } dependenciesLoaded = 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 = overriddenClassName.$isClass ? overriddenClassName : 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); } }; if (className) { Manager.overrideMap[className] = true; } if ('compatibility' in data) { compat = data.compatibility; if (!compat) { compat = false; } else if (typeof compat === 'number') { compat = true; } else if (typeof compat !== 'boolean') { compat = Ext.checkVersion(compat); } } if (compat) { if (overriddenClassName.$isClass) { classReady(); } else { 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); }, 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('platformConfig', function(name, Class, data) { Class.addPlatformConfig(data); }); 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; if (classes[className]) { Manager.classCount--; } delete classes[className]; delete Manager.existCache[className]; delete Manager.classState[className]; Manager.removeName(className); Ext.Factory.clearCaches(); var entry = Manager.getNamespaceEntry(className), scope = entry.parent ? Manager.lookupName(entry.parent, false) : Ext.global, entryName; if (scope) { entryName = entry.name; try { delete scope[entryName]; } catch (e) { scope[entryName] = undefined; } } return entryName; }, 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: function() { var root = global, i; for (i = arguments.length; i-- > 0; ) { root = Manager.lookupName(arguments[i], true); } return root; } }); Ext.addRootNamespaces = Manager.addRootNamespaces; 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.interceptAfterOnce(cls, 'onClassCreated', function() { var cls = this, prototype = cls.prototype, mixins = prototype.mixins, key, mixin; Ext.classSystemMonitor && Ext.classSystemMonitor(cls, 'Ext.ClassManager#aliasPreprocessor#afterClassCreated', arguments); 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 = Ext.Boot.browserPrefixes, browserNames = Ext.Boot.browserNames, enginePrefixes = me.enginePrefixes, engineNames = me.engineNames, browserMatch = userAgent.match(new RegExp('((?:' + Ext.Object.getValues(browserPrefixes).join(')|(?:') + '))([\\w\\._]+)')), engineMatch = userAgent.match(new RegExp('((?:' + Ext.Object.getValues(enginePrefixes).join(')|(?:') + '))([\\w\\._]+)')), browserName = browserNames.other, engineName = engineNames.other, browserVersion = '', engineVersion = '', majorVer = '', isWebView = false, edgeRE = /(Edge\/)([\w.]+)/, ripple = '', i, prefix, name; me.userAgent = userAgent; this.is = function(name) { return !!this.is[name]; }; if (/Edge\//.test(userAgent)) { browserMatch = userAgent.match(edgeRE); engineMatch = userAgent.match(edgeRE); } 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 (browserName && browserVersion) { Ext.setVersion(browserName, browserVersion); } if (userAgent.match(/FB/) && browserName === 'Other') { browserName = browserNames.safari; engineName = engineNames.webkit; } else if (userAgent.match(/Android.*Chrome/g)) { browserName = 'ChromeMobile'; } else { browserMatch = userAgent.match(/OPR\/(\d+.\d+)/); if (browserMatch) { browserName = 'Opera'; 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 = document.documentMode || parseInt(majorVer, 10); for (i = 7; i <= 11; ++i) { prefix = 'isIE' + i; Ext[prefix] = majorVer === i; Ext[prefix + 'm'] = majorVer <= i; Ext[prefix + 'p'] = majorVer >= i; } } 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); try { ripple = window.top.ripple; } catch (e) {} this.setFlag('Ripple', !!document.getElementById("tinyhippos-injected") && !Ext.isEmpty(ripple)); this.setFlag('WebWorks', !!window.blackberry); if (window.PhoneGap !== undefined || window.Cordova !== undefined || window.cordova !== undefined) { isWebView = true; this.setFlag('PhoneGap'); this.setFlag('Cordova'); } 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, engineNames: { edge: 'Edge', webkit: 'WebKit', gecko: 'Gecko', presto: 'Presto', trident: 'Trident', other: 'Other' }, enginePrefixes: { edge: 'Edge/', webkit: 'AppleWebKit/', gecko: 'Gecko/', presto: 'Presto/', trident: 'Trident/' }, 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: '' }, 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; } }; (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 = Ext.Boot.osNames, prefixes = Ext.Boot.osPrefixes, 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 (userAgent.match(/ipad/i)) { platform = 'iPad'; } 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"); } if (this.is.Android4) { browserScope.setFlag("AndroidStock"); browserScope.setFlag("AndroidStock4"); } } }; Ext.env.OS.prototype = { constructor: Ext.env.OS, 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; Ext.isApple = Ext.isMac || Ext.isiOS; 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|ChromeOS/.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.Android && 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, names, test, vector, value; 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; names = test.names; if (value === undefined) { if (!isReady && test.ready) { notRun.push(test); continue; } value = test.fn.call(me, doc, div); } if (name) { supports[name] = has[name] = value; } else if (names) { while (names.length) { name = names.pop(); 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: 'CloneNodeCopiesExpando', fn: function() { var el = document.createElement('div'); el.expandoProp = {}; return el.cloneNode().expandoProp === el.expandoProp; } }, { 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: 'CSS3NegationSelector', fn: function(doc) { try { doc.querySelectorAll("foo:not(bar)"); } catch (e) { return false; } return true; } }, { 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: 'Touch', fn: function() { var maxTouchPoints = navigator.msMaxTouchPoints || navigator.maxTouchPoints; if (Ext.browser.is.Chrome && Ext.browser.version.isLessThanOrEqual(39)) { return (Ext.supports.TouchEvents && maxTouchPoints !== 1) || maxTouchPoints > 1; } else { return Ext.supports.TouchEvents || maxTouchPoints > 0; } } }, { name: 'PointerEvents', fn: function() { return !!(window.PointerEvent && !Ext.supports.TouchEvents); } }, { name: 'MSPointerEvents', fn: function() { return Ext.isIE10; } }, { name: 'TouchEvents', fn: function() { return this.isEventSupported('touchend'); } }, { name: 'TouchAction', ready: true, fn: function(doc, div) { if (!window.getComputedStyle) { return 0; } var values = [ 'pan-x', 'pan-y', 'pinch-zoom', 'double-tap-zoom' ], flags = [ 1, 2, 4, 8 ], ln = values.length, flag = 0, i, value; for (i = 0; i < ln; i++) { value = values[i]; div.style.touchAction = value; if (getComputedStyle(div).touchAction === value) { flag |= flags[i]; } } return flag; } }, { 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: 'Css3dTransforms', fn: function() { return this.has('CssTransforms') && this.isStyleSupported('perspective'); } }, { name: 'CssTransforms', fn: function() { return this.isStyleSupported('transform'); } }, { name: 'CssTransformNoPrefix', fn: function() { return this.isStyleSupportedWithoutPrefix('transform'); } }, { 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: 'XmlQuerySelector', fn: function() { var xmlString = '', xmlDoc; if (window.ActiveXObject) { xmlDoc = new ActiveXObject("Microsoft.xmlDOM"); xmlDoc.async = false; xmlDoc.loadXML(xmlString); } else if (window.DOMParser) { var parser = new DOMParser(); xmlDoc = parser.parseFromString(xmlString, 'text/xml'); } return xmlDoc ? !!xmlDoc.lastChild.querySelector : 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: '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 = doc.createElement('div'), style = el.style; if (el.getBoundingClientRect) { style.position = 'absolute'; style.top = "0"; 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('div', true); 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, style = div.style, pos = style.position; style.position = 'absolute'; outerBox.offsetHeight; style.position = pos; 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.isIE || Ext.isEdge) || (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 && Ext.firefoxVersion < 52); } }, { name: 'AsyncFocusEvents', fn: function() { return Ext.asyncFocus = !!Ext.isIE; } }, { name: 'accessibility', ready: true, fn: function(doc) { var body = doc.body, div, img, style, supports, bgImg; function getColor(colorTxt) { var values = [], colorValue = 0, regex, match; if (colorTxt.indexOf('rgb(') !== -1) { values = colorTxt.replace('rgb(', '').replace(')', '').split(', '); } else if (colorTxt.indexOf('#') !== -1) { regex = colorTxt.length === 7 ? /^#(\S\S)(\S\S)(\S\S)$/ : /^#(\S)(\S)(\S)$/; match = colorTxt.match(regex); if (match) { values = [ '0x' + match[1], '0x' + match[2], '0x' + match[3] ]; } } for (var i = 0; i < values.length; i++) { colorValue += parseInt(values[i]); } return colorValue; } div = doc.createElement('div'); img = doc.createElement('img'); style = div.style; Ext.apply(style, { width: '2px', position: 'absolute', clip: 'rect(1px,1px,1px,1px)', borderWidth: '1px', borderStyle: 'solid', borderTopTolor: '#f00', borderRightColor: '#ff0', backgroundColor: '#fff', backgroundImage: 'url(' + Ext.BLANK_IMAGE_URL + ')' }); img.alt = ''; img.src = Ext.BLANK_IMAGE_URL; div.appendChild(img); body.appendChild(div); style = div.currentStyle || div.style; bgImg = style.backgroundImage; supports = { Images: img.offsetWidth === 1 && img.readyState !== 'uninitialized', BackgroundImages: !(bgImg !== null && (bgImg === "none" || bgImg === "url(invalid-url:)")), BorderColors: style.borderTopColor !== style.borderRightColor, LightOnDark: getColor(style.color) - getColor(style.backgroundColor) > 0 }; Ext.supports.HighContrastMode = !supports.BackgroundImages; body.removeChild(div); div = img = null; return supports; } }, { name: 'ViewportUnits', ready: true, fn: function(doc) { if (Ext.isIE8) { return false; } var body = doc.body, div = document.createElement('div'), style = div.currentStyle || div.style, width, divWidth; body.appendChild(div); Ext.apply(style, { width: '50vw' }); width = parseInt(window.innerWidth / 2, 10); divWidth = parseInt((window.getComputedStyle ? getComputedStyle(div, null) : div.currentStyle).width, 10); body.removeChild(div); div = null; return width === divWidth; } }, { name: 'CSSVariables', ready: false, fn: function() { if (!window.getComputedStyle) { return false; } return window.CSS && window.CSS.supports && window.CSS.supports('--test-var', 0); } }, { name: 'Selectors2', ready: false, fn: function(doc) { try { return !!doc.querySelectorAll(':scope'); } catch (e) { return false; } } }, { name: 'CSSScrollSnap', ready: false, fn: function(doc) { var style = doc.documentElement.style; return 'scrollSnapType' in style || 'webkitScrollSnapType' in style || 'msScrollSnapType' in style; } }, { name: 'TranslateYCausesHorizontalScroll', ready: true, fn: function(doc, div) { div.innerHTML = '
' + '
' + '
a
' + '
' + '
'; return div.firstChild.scrollWidth > div.firstChild.clientWidth; } }, { name: 'FlexBoxBasisBug', ready: true, fn: function() { if (Ext.isIE11 || (Ext.os.is.iOS && Ext.os.version.major <= 10) || (Ext.isSafari && Ext.browser.version.isLessThan(11)) || (Ext.os.is.Android && Ext.os.version.isLessThan(6))) { return true; } return false; } }, { name: 'PercentageSizeFlexBug', ready: true, fn: function(doc, div) { if (Ext.isIE9m) { return false; } var style = div.style; style.display = 'flex'; style.flexDirection = 'column'; style.height = style.width = '100px'; div.innerHTML = '
'; return div.firstChild.firstChild.offsetHeight !== 50; } }, { name: 'CannotScrollExactHeight', fn: function() { return Ext.isIE10p; } }, { name: 'WebKitInputTableBoxModelBug', ready: true, fn: function(doc, div) { var table = document.createElement('div'), cell = document.createElement('div'), input = document.createElement('input'), tableStyle = table.style, cellStyle = cell.style, inputStyle = input.style, body = doc.body, hasBug; input.type = 'text'; tableStyle.display = 'table'; tableStyle.height = '100px'; cellStyle.display = 'table-cell'; inputStyle.border = '0'; inputStyle.padding = '10px'; inputStyle.boxSizing = 'border-box'; inputStyle.height = '100%'; cell.appendChild(input); table.appendChild(cell); body.appendChild(table); hasBug = input.offsetHeight === 80; body.removeChild(table); return hasBug; } }, { name: 'PassiveEventListener', fn: function(doc, div) { var supportsPassive = false, options; try { options = Object.defineProperty({}, 'passive', { get: function() { supportsPassive = true; } }); window.addEventListener('e', null, options); window.removeEventListener('e', null, options); } catch (e) {} return supportsPassive; } }, { name: 'CSSMinContent', ready: true, fn: function(doc, div) { div.innerHTML = '
'; return div.firstChild.offsetHeight === 8; } }, { name: 'ComputedSizeIncludesPadding', ready: true, fn: function(doc, div) { var ret = false, bd = document.body, el, w; if (window.getComputedStyle) { el = document.createElement('div'); el.style.cssText = 'width:10px;padding:2px;' + '-webkit-box-sizing:border-box;box-sizing:border-box;'; bd.appendChild(el); w = window.getComputedStyle(el, null).width; ret = w === '10px'; bd.removeChild(el); } return ret; } }, 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.ticks(); 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.ticks(); me.invokeAll(); Ext._afterReadyTime = Ext.ticks(); } }, 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)) { Ext.undefer(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 = {}, _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: {}, missingCount: 0, missingQueue: {}, syncModeEnabled: false, 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, classes, className, idx, baseUrl, loadlen, l, loadItem; if (src.indexOf("packages/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; loadItem.canonicalPath = true; } } } 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 state = Manager.classState, missingClassNames = [], urls = [], urlByClass = {}, numClasses = classNames.length, url, className, i, numMissing; for (i = 0; i < numClasses; ++i) { className = Manager.resolveName(classNames[i]); if (!Manager.isCreated(className)) { missingClassNames.push(className); if (!state[className]) { urlByClass[className] = Loader.getPath(className); urls.push(urlByClass[className]); } } } numMissing = missingClassNames.length; if (numMissing) { Loader.missingCount += numMissing; Manager.onCreated(function() { if (callback) { Ext.callback(callback, scope, arguments); } Loader.checkReady(); }, Loader, missingClassNames); if (!_config.enabled) { Ext.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, _urlByClass: urlByClass }); } 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(request) { var options = this, entries = request.entries || [], onError = options.onError, error, entry, i; Loader.hasFileLoadError = true; --Loader.scriptsLoading; if (onError) { for (i = 0; i < entries.length; i++) { entry = entries[i]; if (entry.error) { error = new Error('Failed to load: ' + entry.url); break; } } error = error || new Error('Failed to load'); onError.call(options.userScope, options, error, request); } else { Ext.log.error("[Ext.Loader] Some requested files failed to load."); } Loader.checkReady(); }, onLoadSuccess: function() { var options = this, onLoad = options.onLoad, classNames = options._classNames, urlByClass = options._urlByClass, state = Manager.classState, missingQueue = Loader.missingQueue, className, i, len; --Loader.scriptsLoading; if (onLoad) { onLoad.call(options.userScope, options); } for (i = 0 , len = classNames.length; i < len; i++) { className = classNames[i]; if (!state[className]) { missingQueue[className] = urlByClass[className]; } } Loader.checkReady(); }, reportMissingClasses: function() { if (!Loader.syncModeEnabled && !Loader.scriptsLoading && Loader.isLoading && !Loader.hasFileLoadError) { var missingQueue = Loader.missingQueue, 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); }, checkMissingQueue: function() { var missingQueue = Loader.missingQueue, newQueue = {}, name, missing = 0; for (name in missingQueue) { if (!(Manager.classState[name] || Manager.isCreated(name))) { newQueue[name] = missingQueue[name]; missing++; } } Loader.missingCount = missing; Loader.missingQueue = newQueue; }, checkReady: function() { var wasLoading = Loader.isLoading, isLoading; Loader.checkMissingQueue(); isLoading = Loader.missingCount + Loader.scriptsLoading; if (isLoading && !wasLoading) { Ready.block(); Loader.isLoading = !!isLoading; } else if (!isLoading && wasLoading) { Loader.triggerReady(); } if (!Loader.scriptsLoading && Loader.missingCount) { Ext.defer(function() { if (!Loader.scriptsLoading && Loader.missingCount) { Ext.log.error('[Loader] The following classes failed to load:'); for (var name in Loader.missingQueue) { Ext.log.error('[Loader] ' + name + ' from ' + Loader.missingQueue[name]); } } }, 1000); } } }); 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 manifestClasses = Ext.manifest && Ext.manifest.classes, deadlockPath = [], detectDeadlock; if (className && (!manifestClasses || !manifestClasses[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); var requires = _requiresMap[cls], dep, i, ln; if (requires) { if (Ext.Array.contains(requires, className)) { Ext.Error.raise("Circular requirement detected! '" + className + "' and '" + deadlockPath[1] + "' mutually require each other. Path: " + deadlockPath.join(' -> ') + " -> " + deadlockPath[0]); } for (i = 0 , ln = requires.length; i < ln; i++) { dep = requires[i]; if (!isInHistory[dep]) { detectDeadlock(requires[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 uses = data.uses, classNames; if (uses) { classNames = Manager.getNamesByExpression(data.uses); Loader.addUsedClasses(classNames); } }); Manager.onCreated(Loader.historyPush); Loader.init(); }()); Ext._endTime = Ext.ticks(); 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.raise('Use of "beforeHooks" is deprecated - use "before" instead'); } if (mixinConfig.hooks) { Ext.raise('Use of "hooks" is deprecated - use "after" instead'); } if (mixinConfig.afterHooks) { Ext.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() { me.id = null; if (!(scope && scope.destroyed)) { args ? fn.apply(scope, args) : fn.call(scope); } if (fireIdleEvent === false) { Ext._suppressIdle = true; } }; if (fn) { call.$origFn = fn.$origFn || fn; call.$skipTimerCheck = call.$origFn.$skipTimerCheck; } 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; me.delayTime = delay; if (fn) { call.$origFn = fn.$origFn || fn; call.$skipTimerCheck = call.$origFn.$skipTimerCheck; } if (!me.id) { if (delay === -1) { me.id = Ext.raf(call); } else { me.id = Ext.defer(call, delay || 1); } } return me.id; }; me.cancel = function() { if (me.id) { if (me.delayTime === -1) { Ext.unraf(me.id); } else { Ext.undefer(me.id); } me.id = null; } }; me.flush = function() { if (me.id) { me.cancel(); var was = fireIdleEvent; fireIdleEvent = true; call(); fireIdleEvent = was; } }; me.stop = function(stopFn, stopScope) { if (stopFn && stopFn === fn && (!stopScope || stopScope === scope)) { me.cancel(); } }; }; Ext.define('Ext.util.Event', function() { var arraySlice = Array.prototype.slice, arrayInsert = Ext.Array.insert, toArray = Ext.Array.toArray, fireArgs = {}; return { 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, managedListeners; if (scope && !Ext._namedScopes[scope] && (typeof fn === 'string') && (typeof scope[fn] !== 'function')) { Ext.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, options.translate === false).subscribe(observable, eventName, options.delegated !== false, options.capture); } if (manager) { managedListeners = manager.managedListeners || (manager.managedListeners = []); managedListeners.push({ item: me.observable, ename: (options && options.managedName) || me.name, fn: fn, scope: scope, options: options }); } 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.onFrame) { handler = me.createAnimFrame(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, options, manager, managedListeners, managedListener, i; index = index != null ? index : me.findListener(fn, scope); if (index !== -1) { listener = me.listeners[index]; if (me.firing) { me.listeners = me.listeners.slice(0); } me.listeners.splice(index, 1); if (me._highestNegativePriorityIndex) { if (index < me._highestNegativePriorityIndex) { me._highestNegativePriorityIndex--; } else if (index === me._highestNegativePriorityIndex && index === me.listeners.length) { delete me._highestNegativePriorityIndex; } } if (listener) { options = listener.o; if (listener.task) { listener.task.cancel(); delete listener.task; } i = listener.tasks && listener.tasks.length; if (i) { while (i--) { listener.tasks[i].cancel(); } delete listener.tasks; } listener.fireFn.timerId = Ext.undefer(listener.fireFn.timerId); 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 (observable.isElement) { observable._getPublisher(eventName, options.translate === false).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; }, fireDelegated: function(firingObservable, args) { this.firingObservable = firingObservable; return this.fire.apply(this, args); }, fire: function() { var me = this, CQ = Ext.ComponentQuery, listeners = me.listeners, count = listeners.length, observable = me.observable, isElement = observable.isElement, isComponent = observable.isComponent, firingObservable = me.firingObservable, options, delegate, fireInfo, i, args, listener, len, delegateEl, currentTarget, type, chained, firingArgs, e, fireFn, fireScope; 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]; if (!listener) { continue; } options = listener.o; if (isElement) { if (currentTarget) { e.setCurrentTarget(currentTarget); } type = listener.type; if (type) { chained = e; e = args[0] = chained.chain({ type: type, isGesture: false }); } Ext.EventObject = e; } firingArgs = args; if (options) { delegate = options.delegate; if (delegate) { if (isElement) { delegateEl = e.getTarget(typeof delegate === 'function' ? delegate : '#' + e.currentTarget.id + ' ' + delegate); if (delegateEl) { args[1] = delegateEl; currentTarget = e.currentTarget; e.setCurrentTarget(delegateEl); } else { continue; } } else if (isComponent && !CQ.is(firingObservable, delegate, observable)) { continue; } } if (isElement) { 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); fireFn = fireInfo.fn; fireScope = fireInfo.scope; fireInfo.fn = fireInfo.scope = null; if (fireScope && fireScope.destroyed) { me.removeListener(fireFn, fireScope, i); fireFn = null; if (fireScope.$className !== 'Ext.container.Monitor') { (Ext.raiseOnDestroyed ? Ext.raise : Ext.log.warn)({ msg: 'Attempting to fire "' + me.name + '" event on destroyed ' + (fireScope.$className || 'object') + ' instance with id: ' + (fireScope.id || 'unknown'), instance: fireScope }); } } if (fireFn && fireFn.apply(fireScope, firingArgs) === false) { Ext.EventObject = null; return (me.firing = false); } if (options) { args.length--; } if (chained) { e = args[0] = chained; chained = null; } Ext.EventObject = 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.raise('Unable to dynamically resolve scope for "' + listener.ev.name + '" listener on ' + this.observable.id); } if (!Ext.isFunction(scope[fn])) { Ext.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.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.raise('Unable to dynamically resolve method "' + name + '" on ' + this.observable.$className); } return fireArgs; }, createAnimFrame: function(handler, listener, o, scope, wrapped) { var fireInfo; if (!wrapped) { fireInfo = listener.ev.getFireInfo(listener, true); handler = fireInfo.fn; scope = fireInfo.scope; fireInfo.fn = fireInfo.scope = null; } return Ext.Function.createAnimationFrame(handler, scope, o.args); }, 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; fireInfo.fn = fireInfo.scope = null; } return handler.apply(scope, arguments); } }; }, createBuffered: function(handler, listener, o, scope, wrapped) { listener.task = new Ext.util.DelayedTask(); return function() { if (listener.task) { var fireInfo; if (Ext.Timer.track) { o.$delayedTask = listener.task; } if (!wrapped) { fireInfo = listener.ev.getFireInfo(listener, true); handler = fireInfo.fn; scope = fireInfo.scope; fireInfo.fn = fireInfo.scope = null; } 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; fireInfo.fn = fireInfo.scope = null; } if (!listener.tasks) { listener.tasks = []; } listener.tasks.push(task); if (Ext.Timer.track) { o.$delayedTask = task; } task.delay(o.delay || 10, handler, scope, toArray(arguments)); }; }, createSingle: function(handler, listener, o, scope, wrapped) { return function() { var event = listener.ev, observable = event.observable, fn = listener.fn, fireInfo; if (observable) { if (!observable.destroyed) { observable.removeListener(event.name, fn, scope); } } else { event.removeListener(fn, scope); } if (!wrapped) { fireInfo = event.getFireInfo(listener, true); handler = fireInfo.fn; scope = fireInfo.scope; fireInfo.fn = fireInfo.scope = null; } return handler.apply(scope, arguments); }; } }; }); 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 = this.id = prefix + (++uniqueIds[prefix]); } this.getUniqueId = this.getOptimizedId; return id; }, setId: function(id) { this.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); }, protectedProps = [ 'events', 'hasListeners', 'managedListeners', 'eventedBeforeEventNames' ]; ListenerRemover.prototype.destroy = function() { var me = this, args = me.args, observable = me.observable, elementName = args[0].element || (args[3] && args[3].element); if (elementName) { if (Ext.Array.indexOf(observable.referenceList, elementName) === -1) { Ext.Logger.error("Destroying event listener with an invalid element reference of '" + elementName + "' for this component. Available values are: '" + observable.referenceList.join("', '") + "'", observable); } observable = observable[elementName]; } if (!observable.destroyed) { observable[me.managedListeners ? 'mun' : 'un'].apply(observable, me.args); } me.destroy = Ext.emptyFn; }; return { extend: Ext.Mixin, mixinConfig: { id: 'observable', after: { destroy: 'destroyObservable' } }, 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, i, len; 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(); } scope = T.prototype.$noClearOnDestroy || {}; for (i = 0 , len = protectedProps.length; i < len; i++) { scope[protectedProps[i]] = true; } T.prototype.$noClearOnDestroy = scope; } }, isObservable: true, $vetoClearingPrototypeOnDestroy: 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 = me.hasListeners = new me.HasListeners(); me.eventedBeforeEventNames = {}; 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) { if (config) { 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 (item.$observableDestroyed) { return; } 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.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) { if (typeof fn === 'string' && !scope) { fn = this[fn]; } 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); }, $eventedController: { _paused: 1, pause: function() { ++this._paused; }, resume: function() { var me = this, fn = me.fn, scope = me.scope, fnArgs = me.fnArgs, owner = me.owner, args, ret; if (!--me._paused) { if (fn) { args = Ext.Array.slice(fnArgs || me.args); if (fnArgs === false) { args.shift(); } me.fn = null; args.push(me); if (Ext.isFunction(fn)) { ret = fn.apply(scope, args); } else if (scope && Ext.isString(fn) && Ext.isFunction(scope[fn])) { ret = scope[fn].apply(scope, args); } if (ret === false) { return false; } } if (!me._paused) { return me.owner.fireEventArgs(me.eventName, me.args); } } } }, fireEventedAction: function(eventName, args, fn, scope, fnArgs) { var me = this, eventedBeforeEventNames = me.eventedBeforeEventNames, beforeEventName = eventedBeforeEventNames[eventName] || (eventedBeforeEventNames[eventName] = 'before' + eventName), controller = Ext.apply({ owner: me, eventName: eventName, fn: fn, scope: scope, fnArgs: fnArgs, args: args }, me.$eventedController), value; args.push(controller); value = me.fireEventArgs(beforeEventName, args); args.pop(); if (value === false) { return false; } return controller.resume(); }, 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(eventName, fn, scope, options, order, caller) { var me = this, namedScopes = Ext._namedScopes, config, namedScope, isClassListener, innerScope, eventOptions; if (typeof eventName !== 'string') { options = eventName; scope = options.scope; namedScope = scope && namedScopes[scope]; isClassListener = namedScope && namedScope.isSelf; eventOptions = ((me.isComponent || me.isWidget) && options.element) ? me.$elementEventOptions : me.$eventOptions; for (eventName in options) { config = options[eventName]; if (!eventOptions[eventName]) { innerScope = config.scope; if (innerScope && isClassListener) { namedScope = namedScopes[innerScope]; if (namedScope && namedScope.isController) { innerScope = 'self.controller'; } } me.doAddListener(eventName, config.fn || config, innerScope || scope, config.fn ? config : options, order, caller); } } if (options && options.destroyable) { return new ListenerRemover(me, options); } } else { me.doAddListener(eventName, fn, scope, options, order, caller); if (options && options.destroyable) { return new ListenerRemover(me, eventName, fn, scope, options); } } return me; }, removeListener: function(eventName, fn, scope, eventOptions) { var me = this, config, options; if (typeof eventName !== 'string') { options = eventName; eventOptions = eventOptions || me.$eventOptions; for (eventName in options) { if (options.hasOwnProperty(eventName)) { config = options[eventName]; if (!me.$eventOptions[eventName]) { me.doRemoveListener(eventName, config.fn || config, config.scope || options.scope); } } } } else { me.doRemoveListener(eventName, fn, scope); } return me; }, onBefore: function(eventName, fn, scope, options) { return this.addListener(eventName, fn, scope, options, 'before'); }, onAfter: function(eventName, fn, scope, options) { return this.addListener(eventName, fn, scope, options, 'after'); }, unBefore: function(eventName, fn, scope, options) { return this.removeListener(eventName, fn, scope, options, 'before'); }, unAfter: function(eventName, fn, scope, options) { return this.removeListener(eventName, fn, scope, options, 'after'); }, addBeforeListener: function() { return this.onBefore.apply(this, arguments); }, addAfterListener: function() { return this.onAfter.apply(this, arguments); }, removeBeforeListener: function() { return this.unBefore.apply(this, arguments); }, removeAfterListener: function() { return this.unAfter.apply(this, arguments); }, 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.events = null; } 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, i, len; if (managedListeners) { me.managedListeners = null; for (i = 0 , len = managedListeners.length; i < len; i++) { me.removeManagedListenerItem(true, managedListeners[i]); } managedListeners.length = 0; } me.managedListeners = 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))) { if (!managedListener.item.destroyed) { 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(eventName) { eventName = Ext.canonicalEventName(eventName); return !!this.hasListeners[eventName]; }, 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, ename; for (i = 0; i < len; i++) { ename = Ext.canonicalEventName(arguments[i]); event = events[ename]; 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, newName, relayers = {}; if (Ext.isObject(events)) { for (i in events) { newName = events[i]; relayers[i] = me.createRelayer(newName); } } else { 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(); this.destroyObservable(true); }, destroyObservable: function(skipClearListeners) { var me = this, clearPropertiesOnDestroy = me.clearPropertiesOnDestroy; if (me.$observableDestroyed) { return; } if (!skipClearListeners) { me.clearListeners(); } if (me.destroyed) { if (clearPropertiesOnDestroy) { if (clearPropertiesOnDestroy === true && !me.$nulled) { me.$reap(); } if (!me.clearPrototypeOnDestroy) { me.fireEvent = me.fireEventArgs = me.fireAction = me.fireEventedAction = Ext.emptyFn; } me.events = me.managedListeners = me.eventedBeforeEventNames = null; me.$observableDestroyed = true; } if (me.clearPrototypeOnDestroy && Object.setPrototypeOf && !me.$alreadyNulled) { Object.setPrototypeOf(me, null); me.$alreadyNulled = true; } } }, privates: { doAddListener: function(ename, fn, scope, options, order, caller, manager) { var me = this, ret = false, event, 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.raise("Cannot add '" + ename + "' listener to " + me.$className + " instance. No function specified."); } event = (me.events || (me.events = {}))[ename]; if (!event || !event.isEvent) { event = me._initEvent(ename); } if (fn !== emptyFn) { if (!manager && (scope && scope.isObservable && (scope !== me))) { manager = scope; } if (event.addListener(fn, scope, options, caller, manager)) { me.hasListeners._incr_(ename); ret = true; } } return ret; }, doRemoveListener: function(ename, fn, scope) { var me = this, ret = false, events = me.events, event; ename = Ext.canonicalEventName(ename); event = events && events[ename]; if (!fn) { Ext.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); ret = true; } } return ret; }, _initEvent: function(eventName) { return (this.events[eventName] = new Ext.util.Event(this, eventName)); } }, deprecated: { '5.0': { methods: { addEvents: null } } } }; }, 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, count) { if (count == null) { count = 1; } if (!(this[ev] -= count)) { 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 event = (this.methodEvents = this.methodEvents || {})[method], returnValue, v, cancel, me = this, makeCall; if (!event) { me.methodEvents[method] = event = {}; event.originalFn = me[method]; event.methodName = method; event.before = []; event.after = []; makeCall = function(fn, scope, args) { scope = scope || me; if (typeof fn === 'string') { fn = scope[fn]; } if ((v = fn.apply(scope, 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; } } }; me[method] = function() { var args = Array.prototype.slice.call(arguments, 0), argsLen = args.length, b, i, len; returnValue = v = undefined; cancel = false; for (i = 0 , len = event.before.length; i < len; i++) { b = event.before[i]; if (b.extraArgs) { args.push.apply(args, b.extraArgs); } makeCall(b.fn, b.scope, args); args.length = argsLen; if (cancel || b.preventDefault) { return returnValue; } } if ((v = event.originalFn.apply(me, args)) !== undefined) { returnValue = v; } for (i = 0 , len = event.after.length; i < len; i++) { b = event.after[i]; if (b.extraArgs) { args.push.apply(args, b.extraArgs); } makeCall(b.fn, b.scope, args); args.length = argsLen; if (cancel || b.preventDefault) { return returnValue; } } return returnValue; }; } return event; } Ext.apply(proto, { onClassMixedIn: prepareMixin, beforeMethod: function(method, fn, scope, preventDefault, extraArgs) { getMethodEvent.call(this, method).before.push({ fn: fn, scope: scope, extraArgs: extraArgs, preventDefault: preventDefault }); }, afterMethod: function(method, fn, scope, preventDefault, extraArgs) { getMethodEvent.call(this, method).after.push({ fn: fn, scope: scope, extraArgs: extraArgs, preventDefault: preventDefault }); }, removeMethodListener: function(method, fn, scope) { var e = getMethodEvent.call(this, 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; } }, function(HashMap) { var prototype = HashMap.prototype; prototype.removeByKey = prototype.removeAtKey; }); Ext.define('Ext.AbstractManager', { 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.raise('Key is undefined. Please ensure the item has a key before registering the item.'); } if (this.all.containsKey(key)) { Ext.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.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.promise.Consequence', function(Consequence) { return { promise: null, deferred: null, onFulfilled: null, onRejected: null, onProgress: null, constructor: function(onFulfilled, onRejected, onProgress) { var me = this; me.onFulfilled = onFulfilled; me.onRejected = onRejected; me.onProgress = onProgress; me.deferred = new Ext.promise.Deferred(); me.promise = me.deferred.promise; }, trigger: function(action, value) { var me = this, deferred = me.deferred; switch (action) { case 'fulfill': me.propagate(value, me.onFulfilled, deferred, deferred.resolve); break; case 'reject': me.propagate(value, me.onRejected, deferred, deferred.reject); break; } }, update: function(progress) { if (Ext.isFunction(this.onProgress)) { progress = this.onProgress(progress); } this.deferred.update(progress); }, propagate: function(value, callback, deferred, deferredMethod) { if (Ext.isFunction(callback)) { this.schedule(function() { try { deferred.resolve(callback(value)); } catch (e) { deferred.reject(e); } }); } else { deferredMethod.call(this.deferred, value); } }, schedule: function(callback) { var n = Consequence.queueSize++; Consequence.queue[n] = callback; if (!n) { Ext.asap(Consequence.dispatch); } }, statics: { queue: new Array(10000), queueSize: 0, dispatch: function() { var queue = Consequence.queue, fn, i; for (i = 0; i < Consequence.queueSize; ++i) { fn = queue[i]; queue[i] = null; fn(); } Consequence.queueSize = 0; } } }; }, function(Consequence) { Consequence.dispatch.$skipTimerCheck = true; }); Ext.define('Ext.promise.Deferred', { promise: null, consequences: [], completed: false, completionAction: null, completionValue: null, constructor: function() { var me = this; me.promise = new Ext.promise.Promise(me); me.consequences = []; me.completed = false; me.completionAction = null; me.completionValue = null; }, then: function(onFulfilled, onRejected, onProgress) { var me = this, consequence = new Ext.promise.Consequence(onFulfilled, onRejected, onProgress); if (me.completed) { consequence.trigger(me.completionAction, me.completionValue); } else { me.consequences.push(consequence); } return consequence.promise; }, resolve: function(value) { var me = this, isHandled, thenFn; if (me.completed) { return; } try { if (value === me.promise) { throw new TypeError('A Promise cannot be resolved with itself.'); } if (value != null && (typeof value === 'object' || Ext.isFunction(value)) && Ext.isFunction(thenFn = value.then)) { isHandled = false; try { thenFn.call(value, function(value) { if (!isHandled) { isHandled = true; me.resolve(value); } }, function(error) { if (!isHandled) { isHandled = true; me.reject(error); } }); } catch (e1) { if (!isHandled) { me.reject(e1); } } } else { me.complete('fulfill', value); } } catch (e2) { me.reject(e2); } }, reject: function(reason) { if (this.completed) { return; } this.complete('reject', reason); }, update: function(progress) { var consequences = this.consequences, consequence, i, len; if (this.completed) { return; } for (i = 0 , len = consequences.length; i < len; i++) { consequence = consequences[i]; consequence.update(progress); } }, complete: function(action, value) { var me = this, consequences = me.consequences, consequence, i, len; me.completionAction = action; me.completionValue = value; me.completed = true; for (i = 0 , len = consequences.length; i < len; i++) { consequence = consequences[i]; consequence.trigger(me.completionAction, me.completionValue); } me.consequences = null; } }); Ext.define('Ext.promise.Promise', function(ExtPromise) { var Deferred; return { statics: { CancellationError: Ext.global.CancellationError || Error, _ready: function() { Deferred = Ext.promise.Deferred; }, all: function(promisesOrValues) { if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) { Ext.raise('Invalid parameter: expected an Array or Promise of an Array.'); } return ExtPromise.when(promisesOrValues).then(function(promisesOrValues) { var deferred = new Deferred(), remainingToResolve = promisesOrValues.length, results = new Array(remainingToResolve), index, promiseOrValue, resolve, i, len; if (!remainingToResolve) { deferred.resolve(results); } else { resolve = function(item, index) { return ExtPromise.when(item).then(function(value) { results[index] = value; if (!--remainingToResolve) { deferred.resolve(results); } return value; }, function(reason) { return deferred.reject(reason); }); }; for (index = i = 0 , len = promisesOrValues.length; i < len; index = ++i) { promiseOrValue = promisesOrValues[index]; if (index in promisesOrValues) { resolve(promiseOrValue, index); } else { remainingToResolve--; } } } return deferred.promise; }); }, is: function(value) { return value != null && (typeof value === 'object' || Ext.isFunction(value)) && Ext.isFunction(value.then); }, race: function(promises) { if (!Ext.isArray(promises)) { Ext.raise('Invalid parameter: expected an Array.'); } var deferred = new Deferred(), len = promises.length, i; for (i = 0; i < len; ++i) { deferred.resolve(promises[i]); } return deferred.promise; }, rethrowError: function(error) { Ext.asap(function() { throw error; }); }, when: function(value) { var deferred = new Deferred(); deferred.resolve(value); return deferred.promise; } }, owner: null, constructor: function(owner) { this.owner = owner; }, then: function(onFulfilled, onRejected, onProgress, scope) { var ref; if (arguments.length === 1 && Ext.isObject(arguments[0])) { ref = arguments[0]; onFulfilled = ref.success; onRejected = ref.failure; onProgress = ref.progress; scope = ref.scope; } if (scope) { if (onFulfilled) { onFulfilled = onFulfilled.bind(scope); } if (onRejected) { onRejected = onRejected.bind(scope); } if (onProgress) { onProgress = onProgress.bind(scope); } } return this.owner.then(onFulfilled, onRejected, onProgress); }, 'catch': function(onRejected, scope) { var ref; if (arguments.length === 1 && Ext.isObject(arguments[0])) { ref = arguments[0]; onRejected = ref.fn; scope = ref.scope; } if (scope != null) { onRejected = onRejected.bind(scope); } return this.owner.then(null, onRejected); }, otherwise: function(onRejected, scope) { return this['catch'].apply(this, arguments); }, always: function(onCompleted, scope) { var ref; if (arguments.length === 1 && Ext.isObject(arguments[0])) { ref = arguments[0]; onCompleted = ref.fn; scope = ref.scope; } if (scope != null) { onCompleted = onCompleted.bind(scope); } return this.owner.then(function(value) { try { onCompleted(); } catch (e) { ExtPromise.rethrowError(e); } return value; }, function(reason) { try { onCompleted(); } catch (e) { ExtPromise.rethrowError(e); } throw reason; }); }, done: function() { this.owner.then(null, ExtPromise.rethrowError); }, cancel: function(reason) { if (reason == null) { reason = null; } this.owner.reject(new this.self.CancellationError(reason)); }, log: function(identifier) { if (identifier == null) { identifier = ''; } return this.owner.then(function(value) { Ext.log("" + (identifier || 'Promise') + " resolved with value: " + value); return value; }, function(reason) { Ext.log("" + (identifier || 'Promise') + " rejected with reason: " + reason); throw reason; }); } }; }, function(ExtPromise) { ExtPromise._ready(); }); Ext.define('Ext.Promise', function() { var Polyfiller; return { statics: { _ready: function() { Polyfiller = Ext.promise.Promise; }, all: function() { return Polyfiller.all.apply(Polyfiller, arguments); }, race: function() { return Polyfiller.race.apply(Polyfiller, arguments); }, reject: function(reason) { var deferred = new Ext.promise.Deferred(); deferred.reject(reason); return deferred.promise; }, resolve: function(value) { var deferred = new Ext.promise.Deferred(); deferred.resolve(value); return deferred.promise; } }, constructor: function(action) { var deferred = new Ext.promise.Deferred(); action(deferred.resolve.bind(deferred), deferred.reject.bind(deferred)); return deferred.promise; } }; }, function(ExtPromise) { var P = Ext.global.Promise; if (P && P.resolve && !Ext.useExtPromises) { Ext.Promise = P; } else { ExtPromise._ready(); } }); Ext.define('Ext.Deferred', function(Deferred) { var ExtPromise, rejected, resolved, when; return { extend: Ext.promise.Deferred, statics: { _ready: function() { ExtPromise = Ext.promise.Promise; when = Ext.Promise.resolve; }, all: function() { return ExtPromise.all.apply(ExtPromise, arguments); }, any: function(promisesOrValues) { if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) { Ext.raise('Invalid parameter: expected an Array or Promise of an Array.'); } return Deferred.some(promisesOrValues, 1).then(function(array) { return array[0]; }, function(error) { if (error instanceof Error && error.message === 'Too few Promises were resolved.') { Ext.raise('No Promises were resolved.'); } else { throw error; } }); }, delay: function(promiseOrValue, milliseconds) { var deferred; if (arguments.length === 1) { milliseconds = promiseOrValue; promiseOrValue = undefined; } milliseconds = Math.max(milliseconds, 1); deferred = new Deferred(); deferred.timeoutId = Ext.defer(function() { delete deferred.timeoutId; deferred.resolve(promiseOrValue); }, milliseconds); return deferred.promise; }, getCachedRejected: function() { if (!rejected) { rejected = Ext.Promise.reject(); } return rejected; }, getCachedResolved: function() { if (!resolved) { resolved = Ext.Promise.resolve(); } return resolved; }, map: function(promisesOrValues, mapFn) { if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) { Ext.raise('Invalid parameter: expected an Array or Promise of an Array.'); } if (!Ext.isFunction(mapFn)) { Ext.raise('Invalid parameter: expected a function.'); } return Deferred.resolved(promisesOrValues).then(function(promisesOrValues) { var deferred, index, promiseOrValue, remainingToResolve, resolve, results, i, len; remainingToResolve = promisesOrValues.length; results = new Array(promisesOrValues.length); deferred = new Deferred(); if (!remainingToResolve) { deferred.resolve(results); } else { resolve = function(item, index) { return Deferred.resolved(item).then(function(value) { return mapFn(value, index, results); }).then(function(value) { results[index] = value; if (!--remainingToResolve) { deferred.resolve(results); } return value; }, function(reason) { return deferred.reject(reason); }); }; for (index = i = 0 , len = promisesOrValues.length; i < len; index = ++i) { promiseOrValue = promisesOrValues[index]; if (index in promisesOrValues) { resolve(promiseOrValue, index); } else { remainingToResolve--; } } } return deferred.promise; }); }, memoize: function(fn, scope, hashFn) { var memoizedFn = Ext.Function.memoize(fn, scope, hashFn); return function() { return Deferred.all(Ext.Array.slice(arguments)).then(function(values) { return memoizedFn.apply(scope, values); }); }; }, parallel: function(fns, scope) { if (scope == null) { scope = null; } var args = Ext.Array.slice(arguments, 2); return Deferred.map(fns, function(fn) { if (!Ext.isFunction(fn)) { throw new Error('Invalid parameter: expected a function.'); } return fn.apply(scope, args); }); }, pipeline: function(fns, initialValue, scope) { if (scope == null) { scope = null; } return Deferred.reduce(fns, function(value, fn) { if (!Ext.isFunction(fn)) { throw new Error('Invalid parameter: expected a function.'); } return fn.call(scope, value); }, initialValue); }, race: function() { return ExtPromise.race.apply(ExtPromise, arguments); }, reduce: function(values, reduceFn, initialValue) { if (!(Ext.isArray(values) || ExtPromise.is(values))) { Ext.raise('Invalid parameter: expected an Array or Promise of an Array.'); } if (!Ext.isFunction(reduceFn)) { Ext.raise('Invalid parameter: expected a function.'); } var initialValueSpecified = arguments.length === 3; return Deferred.resolved(values).then(function(promisesOrValues) { var reduceArguments = [ promisesOrValues, function(previousValueOrPromise, currentValueOrPromise, currentIndex) { return Deferred.resolved(previousValueOrPromise).then(function(previousValue) { return Deferred.resolved(currentValueOrPromise).then(function(currentValue) { return reduceFn(previousValue, currentValue, currentIndex, promisesOrValues); }); }); } ]; if (initialValueSpecified) { reduceArguments.push(initialValue); } return Ext.Array.reduce.apply(Ext.Array, reduceArguments); }); }, rejected: function(reason) { var deferred = new Ext.Deferred(); deferred.reject(reason); return deferred.promise; }, resolved: function(promiseOrValue) { var deferred = new Ext.Deferred(); deferred.resolve(promiseOrValue); return deferred.promise; }, sequence: function(fns, scope) { if (scope == null) { scope = null; } var args = Ext.Array.slice(arguments, 2); return Deferred.reduce(fns, function(results, fn) { if (!Ext.isFunction(fn)) { throw new Error('Invalid parameter: expected a function.'); } return Deferred.resolved(fn.apply(scope, args)).then(function(result) { results.push(result); return results; }); }, []); }, some: function(promisesOrValues, howMany) { if (!(Ext.isArray(promisesOrValues) || ExtPromise.is(promisesOrValues))) { Ext.raise('Invalid parameter: expected an Array or Promise of an Array.'); } if (!Ext.isNumeric(howMany) || howMany <= 0) { Ext.raise('Invalid parameter: expected a positive integer.'); } return Deferred.resolved(promisesOrValues).then(function(promisesOrValues) { var deferred, index, onReject, onResolve, promiseOrValue, remainingToReject, remainingToResolve, values, i, len; values = []; remainingToResolve = howMany; remainingToReject = (promisesOrValues.length - remainingToResolve) + 1; deferred = new Deferred(); if (promisesOrValues.length < howMany) { deferred.reject(new Error('Too few Promises were resolved.')); } else { onResolve = function(value) { if (remainingToResolve > 0) { values.push(value); } remainingToResolve--; if (remainingToResolve === 0) { deferred.resolve(values); } return value; }; onReject = function(reason) { remainingToReject--; if (remainingToReject === 0) { deferred.reject(new Error('Too few Promises were resolved.')); } return reason; }; for (index = i = 0 , len = promisesOrValues.length; i < len; index = ++i) { promiseOrValue = promisesOrValues[index]; if (index in promisesOrValues) { Deferred.resolved(promiseOrValue).then(onResolve, onReject); } } } return deferred.promise; }); }, timeout: function(promiseOrValue, milliseconds) { var deferred = new Deferred(), timeoutId; timeoutId = Ext.defer(function() { if (timeoutId) { deferred.reject(new Error('Promise timed out.')); } }, milliseconds); Deferred.resolved(promiseOrValue).then(function(value) { Ext.undefer(timeoutId); timeoutId = null; deferred.resolve(value); }, function(reason) { Ext.undefer(timeoutId); timeoutId = null; deferred.reject(reason); }); return deferred.promise; } } }; }, function(Deferred) { Deferred._ready(); }); Ext.Factory = function(type) { var me = this; me.aliasPrefix = type + '.'; me.cache = {}; me.name = type.replace(me.fixNameRe, me.fixNameFn); me.type = type; me.creator = 'create' + Ext.String.capitalize(me.name); }; Ext.Factory.prototype = { defaultProperty: 'type', instanceProp: 'isInstance', typeProperty: 'type', create: function(config, defaultType) { var me = this, Manager = Ext.ClassManager, cache = me.cache, typeProperty = me.typeProperty, 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[typeProperty]; } if (defaultType && defaultType.constructor === Object) { config = Ext.apply({}, config, defaultType); defaultType = defaultType[typeProperty]; } 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.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 = {}; this.instanceCache = {}; }, hook: function(fn) { var me = this, original = me.create; me.create = function(config, defaultType) { var ret = fn.call(me, original, config, defaultType); if (ret === undefined) { ret = original.call(me, config, defaultType); } return ret; }; }, update: function(instance, config, creator, creatorMethod, defaultsConfig) { var me = this, aliases, defaults, reuse, type; if (!config || config.isInstance) { if (config && !config[me.instanceProp]) { Ext.raise('Config instance failed ' + me.instanceProp + ' requirement'); } if (instance && instance !== config) { instance.destroy(); } return config; } if (typeof config === 'string') { type = config; config = {}; config[me.defaultProperty] = type; } if (instance) { if (config === true) { return instance; } if (!(type = config.xclass)) { if (!(type = config.xtype)) { type = config[me.typeProperty]; if (type) { type = me.aliasPrefix + type; aliases = instance.self.prototype; if (aliases.hasOwnProperty('alias')) { aliases = aliases.alias; if (aliases) { reuse = aliases === type || aliases.indexOf(type) > -1; } } } } else { reuse = instance.isXType(type, true); } } else { reuse = instance.$className === type; } if (reuse) { instance.setConfig(config); return instance; } instance.destroy(); } if (config === true) { config = {}; } if (creator) { if (defaultsConfig) { defaults = Ext.Config.map[defaultsConfig]; defaults = creator[defaults.names.get](); if (defaults) { config = Ext.merge(Ext.clone(defaults), config); } } creatorMethod = creatorMethod || me.creator; if (creator[creatorMethod]) { config = creator[creatorMethod](config); if (!config) { Ext.raise('Missing return value from ' + creatorMethod + ' on class ' + creator.$className); } } } return me.create(config); } }; Ext.Factory.define = function(type, config) { var Factory = Ext.Factory, cacheable = config && config.cacheable, 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 = function(config, defaultType) { return factory.create(config, defaultType); }; if (cacheable) { factory.instanceCache = {}; factory.hook(function(original, config, defaultType) { var cache = this.instanceCache, v; if (typeof config === 'string' && !(v = cache[config])) { v = original.call(this, config, defaultType); if (v.cacheable !== false) { cache[config] = v; Ext.Object.freeze(v); } } return v; }); } fn.instance = factory; fn.update = function(instance, config, creator, creatorMethod, defaultsConfig) { return factory.update(instance, config, creator, creatorMethod, defaultsConfig); }; } return fn; }; Ext.Factory.clearCaches = function() { var Factory = Ext.Factory, key, item; for (key in Factory) { item = Factory[key]; item = item.instance; if (item) { item.clearCache(); } } }; Ext.Factory.on = function(name, fn) { Ext.Factory[name].instance.hook(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.data.request.Base', { mixins: [ Ext.mixin.Factoryable ], factoryConfig: { type: 'request', defaultType: 'ajax' }, result: null, success: null, timer: null, constructor: function(config) { var me = this; Ext.apply(me, config.options || {}, config.ownerConfig); me.id = ++Ext.data.Connection.requestId; me.owner = config.owner; me.options = config.options; me.requestOptions = config.requestOptions; }, start: function() { var me = this, timeout = me.getTimeout(); if (timeout && me.async) { me.timer = Ext.defer(me.onTimeout, timeout, me); } }, abort: function() { var me = this; me.clearTimer(); if (!me.timedout) { me.aborted = true; } me.abort = Ext.emptyFn; }, createDeferred: function() { var me = this, result = me.result, d = new Ext.Deferred(); if (me.completed) { if (me.success) { d.resolve(result); } else { d.reject(result); } } me.deferred = d; return d; }, getDeferred: function() { return this.deferred || this.createDeferred(); }, getPromise: function() { return this.getDeferred().promise; }, then: function() { var promise = this.getPromise(); return promise.then.apply(promise, arguments); }, onComplete: function() { var me = this, deferred = me.deferred, result = me.result; me.clearTimer(); if (deferred) { if (me.success) { deferred.resolve(result); } else { deferred.reject(result); } } me.completed = true; }, onTimeout: function() { var me = this; me.timedout = true; me.timer = null; me.abort(true); }, getTimeout: function() { return this.timeout; }, clearTimer: function() { this.timer = Ext.undefer(this.timer); }, destroy: function() { var me = this; me.abort(); me.owner = me.options = me.requestOptions = me.result = null; me.callParent(); }, privates: { createException: function() { var me = this, result; result = { request: me, requestId: me.id, status: me.aborted ? -1 : 0, statusText: me.aborted ? 'transaction aborted' : 'communication failure', getResponseHeader: me._getHeader, getAllResponseHeaders: me._getHeaders }; if (me.aborted) { result.aborted = true; } if (me.timedout) { result.timedout = true; } return result; }, _getHeader: function(name) { var headers = this.headers; return headers && headers[name.toLowerCase()]; }, _getHeaders: function() { return this.headers; } } }); 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.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.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.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.request.Ajax', { extend: Ext.data.request.Base, alias: 'request.ajax', statics: { parseStatus: function(status, response) { var type, len; if (response) { type = response.responseType; if (type === 'arraybuffer') { len = response.byteLength; } else if (type === 'blob') { len = response.response.size; } else if (type === 'json' || type === 'document') { len = 0; } else if ((type === 'text' || type === '' || !type) && response.responseText) { len = response.responseText.length; } } status = status == 1223 ? 204 : status; var success = (status >= 200 && status < 300) || status == 304 || (status == 0 && Ext.isNumber(len)), 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 }; } }, start: function(data) { var me = this, options = me.options, requestOptions = me.requestOptions, isXdr = me.isXdr, xhr, headers; xhr = me.xhr = me.openRequest(options, requestOptions, me.async, me.username, me.password); if (!isXdr) { headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params); } if (me.async) { if (!isXdr) { xhr.onreadystatechange = me.bindStateChange(); } } if (isXdr) { me.processXdrRequest(me, xhr); } me.callParent([ data ]); xhr.send(data); if (!me.async) { return me.onComplete(); } return me; }, abort: function(force) { var me = this, xhr = me.xhr; if (force || me.isLoading()) { try { xhr.onreadystatechange = null; } catch (e) { xhr.onreadystatechange = Ext.emptyFn; } xhr.abort(); me.callParent([ force ]); me.onComplete(); me.cleanup(); } }, cleanup: function() { this.xhr = null; delete this.xhr; }, isLoading: function() { var me = this, xhr = me.xhr, state = xhr && xhr.readyState, C = Ext.data.flash && Ext.data.flash.BinaryXhr; if (!xhr || me.aborted || me.timedout) { return false; } if (C && xhr instanceof C) { return state !== 4; } return state !== 0 && state !== 4; }, 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.isXdr) { xhr.open(requestOptions.method, requestOptions.url); } else { xhr.open(requestOptions.method, requestOptions.url, async); } } if (options.binary || me.binary) { 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.responseType) { xhr.responseType = options.responseType; } if (options.withCredentials || me.withCredentials) { xhr.withCredentials = true; } return xhr; }, newRequest: function(options) { var me = this, xhr; if (options.binaryData) { if (window.Uint8Array) { xhr = me.getXhrInstance(); } else { xhr = new Ext.data.flash.BinaryXhr(); } } else if (me.cors && Ext.isIE9m) { xhr = me.getXdrInstance(); me.isXdr = true; } else { xhr = me.getXhrInstance(); me.isXdr = false; } return xhr; }, setupHeaders: function(xhr, options, data, params) { var me = this, headers = Ext.apply({}, options.headers || {}, me.defaultHeaders), contentType = me.defaultPostHeader, jsonData = options.jsonData, xmlData = options.xmlData, type = 'Content-Type', useHeader = me.useDefaultXhrHeader, 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.defaultXhrHeader; } 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.owner.fireEvent('exception', key, header); } return headers; }, getXdrInstance: function() { var xdr; if (Ext.ieVersion >= 8) { xdr = new XDomainRequest(); } else { Ext.raise({ msg: 'Your browser does not support CORS' }); } return xdr; }, getXhrInstance: function() { return new XMLHttpRequest(); }, processXdrRequest: function(request, xhr) { var me = this; delete request.headers; request.contentType = request.options.contentType || me.defaultXdrContentType; xhr.onload = me.bindStateChange(true); xhr.onerror = xhr.ontimeout = me.bindStateChange(false); }, processXdrResponse: function(response, xhr) { response.getAllResponseHeaders = function() { return []; }; response.getResponseHeader = function() { return ''; }; response.contentType = xhr.contentType || this.defaultXdrContentType; }, bindStateChange: function(xdrResult) { var me = this; return function() { Ext.elevate(function() { me.onStateChange(xdrResult); }); }; }, onStateChange: function(xdrResult) { var me = this, xhr = me.xhr; if ((xhr && xhr.readyState == 4) || me.isXdr) { me.clearTimer(); me.onComplete(xdrResult); me.cleanup(); } }, onComplete: function(xdrResult) { var me = this, owner = me.owner, options = me.options, xhr = me.xhr, failure = { success: false, isException: false }, result, success, response; if (!xhr || me.destroyed) { return me.result = failure; } try { result = Ext.data.request.Ajax.parseStatus(xhr.status, xhr); if (result.success) { result.success = xhr.readyState === 4; } } catch (e) { result = failure; } success = me.success = me.isXdr ? xdrResult : result.success; if (success) { response = me.createResponse(xhr); if (owner.hasListeners.requestcomplete) { owner.fireEvent('requestcomplete', owner, response, options); } if (options.success) { Ext.callback(options.success, options.scope, [ response, options ]); } } else { if (result.isException || me.aborted || me.timedout) { response = me.createException(xhr); } else { response = me.createResponse(xhr); } if (owner.hasListeners.requestexception) { owner.fireEvent('requestexception', owner, response, options); } if (options.failure) { Ext.callback(options.failure, options.scope, [ response, options ]); } } me.result = response; if (options.callback) { Ext.callback(options.callback, options.scope, [ options, success, response ]); } owner.onRequestComplete(me); me.callParent([ xdrResult ]); return response; }, createResponse: function(xhr) { var me = this, isXdr = me.isXdr, 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); } } response = { request: me, requestId: me.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 (me.binary) { response.responseBytes = me.getByteArray(xhr); } else { if (xhr.responseType) { response.responseType = xhr.responseType; } if (xhr.responseType === 'blob') { response.responseBlob = xhr.response; } else if (xhr.responseType === 'json') { response.responseJson = xhr.response; } else if (xhr.responseType === 'document') { response.responseXML = xhr.response; } else { response.responseText = xhr.responseText; response.responseXML = xhr.responseXML; } } return response; }, destroy: function() { this.xhr = null; this.callParent(); }, privates: { 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; } } }); Ext.define('Ext.data.request.Form', { extend: Ext.data.request.Base, alias: 'request.form', start: function(data) { var me = this, options = me.options, requestOptions = me.requestOptions; me.callParent([ data ]); me.form = me.upload(options.form, requestOptions.url, requestOptions.data, options); return me; }, abort: function(force) { var me = this, frame; if (me.isLoading()) { try { frame = me.frame.dom; if (frame.stop) { frame.stop(); } else { frame.document.execCommand('Stop'); } } catch (e) {} } me.callParent([ force ]); me.onComplete(); me.cleanup(); }, cleanup: function() { var me = this, frame = me.frame; if (frame) { frame.un('load', me.onComplete, me); Ext.removeNode(frame); } me.frame = me.form = null; }, isLoading: function() { return !!this.frame; }, upload: function(form, url, params, options) { form = Ext.getDom(form); options = options || {}; var frameDom = document.createElement('iframe'), frame = Ext.get(frameDom), id = frame.id, 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; frame.set({ name: id, cls: Ext.baseCSSPrefix + 'hidden-display', src: Ext.SSL_SECURE_URL, tabIndex: -1 }); document.body.appendChild(frameDom); document.body.appendChild(form); 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); } } } } this.frame = frame; frame.on({ load: this.onComplete, scope: this, single: !Ext.isOpera }); form.submit(); document.body.removeChild(form); Ext.fly(form).set(buf); for (hLen = hiddens.length , h = 0; h < hLen; h++) { Ext.removeNode(hiddens[h]); } return form; }, getDoc: function() { var frame = this.frame.dom; return (frame && (frame.contentWindow.document || frame.contentDocument)) || (window.frames[frame.id] || {}).document; }, getTimeout: function() { return this.options.timeout; }, onComplete: function() { var me = this, frame = me.frame, owner = me.owner, options = me.options, callback, doc, success, contentNode, response; if (!frame) { return; } if (me.aborted || me.timedout) { me.result = response = me.createException(); response.responseXML = null; response.responseText = Ext.encode({ success: false, message: Ext.String.trim(response.statusText) }); response.request = me; callback = options.failure; success = false; } else { try { doc = me.getDoc(); me.result = response = { responseText: '', responseXML: null, request: me }; 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; response.status = 200; } else { Ext.raise("Could not acquire a suitable connection for the file upload service."); } } catch (e) { me.result = response = me.createException(); response.status = 400; response.statusText = (e.message || e.description) + ''; response.responseText = Ext.encode({ success: false, message: Ext.String.trim(response.statusText) }); response.responseXML = null; callback = options.failure; success = false; } } me.frame = null; me.success = success; owner.fireEvent(success ? 'requestcomplete' : 'requestexception', owner, response, options); Ext.callback(callback, options.scope, [ response, options ]); Ext.callback(options.callback, options.scope, [ options, success, response ]); owner.onRequestComplete(me); Ext.asap(frame.destroy, frame); me.callParent(); }, destroy: function() { this.cleanup(); this.callParent(); } }); Ext.define('Ext.data.Connection', { mixins: { observable: Ext.mixin.Observable }, statics: { requestId: 0 }, enctypeRe: /multipart\/form-data/i, 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, requestOptions, request; if (me.fireEvent('beforerequest', me, options) !== false) { requestOptions = me.setOptions(options, options.scope || Ext.global); request = me.createRequest(options, requestOptions); return request.start(requestOptions.data); } request = { status: -1, statusText: 'Request cancelled in beforerequest event handler' }; Ext.callback(options.callback, options.scope, [ options, false, request ]); return Ext.Deferred.rejected([ options, false, request ]); }, createRequest: function(options, requestOptions) { var me = this, type = options.type || requestOptions.type, request; if (!type) { type = me.isFormUpload(options) ? 'form' : 'ajax'; } if (options.autoAbort || me.getAutoAbort()) { me.abort(); } request = Ext.Factory.request({ type: type, owner: me, options: options, requestOptions: requestOptions, ownerConfig: me.getConfig() }); me.requests[request.id] = request; me.latestId = request.id; return request; }, isFormUpload: function(options) { var form = this.getForm(options); if (form) { return options.isUpload || this.enctypeRe.test(form.getAttribute('enctype')); } return false; }, getForm: function(options) { return Ext.getDom(options.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.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; }, isLoading: function(request) { if (!request) { request = this.getLatest(); } return request ? request.isLoading() : false; }, abort: function(request) { if (!request) { request = this.getLatest(); } if (request && request.isLoading()) { request.abort(); } }, abortAll: function() { var requests = this.requests, id; for (id in requests) { this.abort(requests[id]); } }, getLatest: function() { var id = this.latestId, request; if (id) { request = this.requests[id]; } return request || null; }, clearTimeout: function(request) { if (!request) { request = this.getLatest(); } if (request) { request.clearTimer(); } }, onRequestComplete: function(request) { delete this.requests[request.id]; }, 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() { var me = this; me.queue = []; me.taskQueue = []; me.runningQueue = []; me.idleQueue = []; me.isRunning = false; me.isIdle = true; me.run = me.run.bind(me); if (Ext.os.is.iOS) { me.watch.$skipTimerCheck = true; me.watchdogTimer = Ext.interval(me.watch, 500, me); } }, start: function(fn, scope, args) { var me = this; me.queue.push(arguments); if (!me.isRunning) { if (me.hasOwnProperty('idleTimer')) { Ext.undefer(me.idleTimer); delete me.idleTimer; } if (me.hasOwnProperty('idleQueueTimer')) { Ext.undefer(me.idleQueueTimer); delete me.idleQueueTimer; } me.isIdle = false; me.isRunning = true; me.startCountTime = Ext.now(); me.count = 0; me.doStart(); } }, clear: function() { var me = this; Ext.undefer(me.idleTimer); Ext.undefer(me.idleQueueTimer); Ext.unraf(me.animationFrameId); me.idleTimer = me.idleQueueTimer = me.animationFrameId = null; me.queue.length = me.taskQueue.length = me.runningQueue.length = me.idleQueue.length = 0; me.isRunning = false; me.isIdle = true; me.startCountTime = Ext.now(); me.count = 0; }, watch: function() { if (this.isRunning && Ext.now() - this.lastRunTime >= 500) { this.run(); } }, run: function() { var me = this, item, element; me.animationFrameId = null; if (!me.isRunning) { return; } var queue = me.runningQueue, now = Ext.now(), i, ln; me.lastRunTime = now; me.frameStartTime = now; i = me.queue.length; while (i--) { item = me.queue[i]; element = item[1] && item[1].getElement && item[1].getElement(); if (element && element.destroyed) { me.queue.splice(i, 1); } } queue.push.apply(queue, me.queue); for (i = 0 , ln = queue.length; i < ln; i++) { me.invoke(queue[i]); } queue.length = 0; var elapse = me.frameStartTime - me.startCountTime, count = ++me.count; if (elapse >= 200) { me.onFpsChanged(count * 1000 / elapse, count, elapse); me.startCountTime = me.frameStartTime; me.count = 0; } if (!me.queue.length) { me.stop(); } if (me.isRunning) { me.doIterate(); } }, onFpsChanged: Ext.emptyFn, onStop: Ext.emptyFn, doStart: function() { if (!this.animationFrameId) { this.animationFrameId = Ext.raf(this.run); } this.lastRunTime = Ext.now(); }, doIterate: function() { if (!this.animationFrameId) { this.animationFrameId = Ext.raf(this.run); } }, doStop: function() { if (this.animationFrameId) { Ext.unraf(this.animationFrameId); } this.animationFrameId = null; }, stop: function(fn, scope, args) { var me = this; if (!me.isRunning) { return; } var queue = me.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) { me.doStop(); me.onStop(); me.isRunning = false; if (me.idleQueue.length && !me.idleTimer) { me.idleTimer = Ext.defer(me.whenIdle, 100, me); } } }, onIdle: function(fn, scope, args) { var me = this, listeners = me.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 (me.isIdle) { me.processIdleQueue(); } else if (!me.idleTimer) { me.idleTimer = Ext.defer(me.whenIdle, 100, me); } }, unIdle: function(fn, scope, args) { var me = this, listeners = me.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; } } if (!listeners.length && me.idleTimer) { Ext.undefer(me.idleTimer); delete me.idleTimer; } if (!listeners.length && me.idleQueueTimer) { Ext.undefer(me.idleQueueTimer); delete me.idleQueueTimer; } 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() { delete this.idleTimer; 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() { var styleTpl = { color: 'white', 'background-color': 'black', 'text-align': 'center', 'font-family': 'sans-serif', 'font-size': '8px', 'font-weight': 'normal', 'font-style': 'normal', 'line-height': '20px', '-webkit-font-smoothing': 'antialiased', 'zIndex': 100000, position: 'absolute' }; Ext.getBody().append([ { style: Ext.applyIf({ bottom: '50px', left: 0, width: '50px', height: '20px' }, styleTpl), html: 'Average' }, { style: Ext.applyIf({ 'background-color': 'red', 'font-size': '18px', 'line-height': '50px', bottom: 0, left: 0, width: '50px', height: '50px' }, styleTpl), id: '__averageFps', html: '0' }, { style: Ext.applyIf({ bottom: '50px', left: '50px', width: '50px', height: '20px' }, styleTpl), html: 'Min (Last 1k)' }, { style: Ext.applyIf({ 'background-color': 'orange', 'font-size': '18px', 'line-height': '50px', bottom: 0, left: '50px', width: '50px', height: '50px' }, styleTpl), id: '__minFps', html: '0' }, { style: Ext.applyIf({ bottom: '50px', left: '100px', width: '50px', height: '20px' }, styleTpl), html: 'Max (Last 1k)' }, { style: Ext.applyIf({ 'background-color': 'maroon', 'font-size': '18px', 'line-height': '50px', bottom: 0, left: '100px', width: '50px', height: '50px' }, styleTpl), id: '__maxFps', html: '0' }, { style: Ext.applyIf({ bottom: '50px', left: '150px', width: '50px', height: '20px' }, styleTpl), html: 'Current' }, { style: Ext.applyIf({ 'background-color': 'green', 'font-size': '18px', 'line-height': '50px', bottom: 0, left: '150px', width: '50px', height: '50px' }, styleTpl), id: '__currentFps', html: '0' } ]); Ext.AnimationQueue.resetFps(); }, resetFps: function() { var currentFps = Ext.get('__currentFps'), averageFps = Ext.get('__averageFps'), minFps = Ext.get('__minFps'), maxFps = Ext.get('__maxFps'), min = 1000, max = 0, count = 0, sum = 0; if (!currentFps) { return; } 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.onReady(this.showFps.bind(this)); } }); Ext.define('Ext.mixin.Bufferable', function(Bufferable) { return { extend: Ext.Mixin, mixinConfig: { id: 'bufferable', before: { destroy: 'cancelAllCalls' }, extended: function(baseClass, derivedClass, classBody) { var bufferableMethods = classBody.bufferableMethods; if (bufferableMethods) { delete classBody.bufferableMethods; Bufferable.processClass(derivedClass, bufferableMethods); } } }, afterClassMixedIn: function(targetClass) { Bufferable.processClass(targetClass); }, privates: { cancelAllCalls: function() { var bufferables = this.bufferables, name; if (bufferables) { for (name in bufferables) { bufferables[name].cancel(); delete bufferables[name]; } } }, cancelBufferedCall: function(name, invoke) { var bufferables = this.bufferables, timer = bufferables && bufferables[name]; if (timer) { timer[invoke ? 'invoke' : 'cancel'](); } return !!timer; }, flushBufferedCall: function(name) { return this.cancelBufferedCall(name, true); }, initBufferables: function() { var me = this, methods = me.hasOwnProperty('bufferableMethods') && me.bufferableMethods, classMethods; if (methods) { Bufferable._canonicalize(methods); classMethods = me.self.prototype.bufferableMethods; me.bufferableMethods = Ext.merge(Ext.clone(classMethods), methods); } return (me.bufferables = {}); }, isCallPending: function(name) { var bufferables = this.bufferables, timer = bufferables && bufferables[name]; return !!timer; }, statics: { SINGLE: { single: true }, _canonicalize: function(methods) { var t, def, s, name; for (name in methods) { s = Ext.String.capitalize(name); def = methods[name]; t = typeof def; if (t === 'number' || t === 'string') { methods[name] = def = { delay: def }; } if (typeof (t = def.delay) === 'string') { def[t] = true; delete def.delay; } def.capitalized = s; def.name = name; if (!def.fn) { def.fn = 'do' + s; } if (!def.flag) { def.flag = 'is' + s + 'Pending'; } } }, _canceller: function() { var timer = this, id = timer.id; if (id) { if (timer.delay) { Ext.undefer(id); } else if (timer.asap) { Ext.unasap(id); } else if (timer.idle) { Ext.un('idle', id, null, Bufferable.SINGLE); } else if (timer.raf) { Ext.unraf(id); } timer.id = null; } timer.args = null; timer.target[timer.flag] = false; }, _invoker: function() { var timer = this, args = timer.args || Ext.emptyArray, target = timer.target; ++timer.invokes; timer.cancel(); target[timer.fn].apply(target, args); }, delayCall: function(target, def, args) { var bufferables = target.bufferables || target.initBufferables(), name = def.name, timer = bufferables[name] || (bufferables[name] = Ext.apply({ calls: 0, invokes: 0, args: null, cancel: Bufferable._canceller, id: null, target: target, invoke: Bufferable._invoker }, def)), delay = def.delay, exec = function() { if (timer.id) { timer.id = null; timer.invoke(); } }; if (timer.id) { timer.cancel(); } timer.args = args; ++timer.calls; target[timer.flag] = true; if (delay) { timer.id = Ext.defer(exec, delay); } else if (def.asap) { timer.id = Ext.asap(exec); } else if (def.idle) { timer.id = exec; Ext.on('idle', exec, null, Bufferable.SINGLE); } else if (def.raf) { timer.id = Ext.raf(exec); } else { timer.invoke(); } }, processClass: function(cls, bufferableMethods) { var proto = cls.prototype, inherited = proto.bufferableMethods, def, name; if (bufferableMethods) { Bufferable._canonicalize(bufferableMethods); if (inherited) { inherited = Ext.merge(Ext.clone(inherited), bufferableMethods); } proto.bufferableMethods = inherited || bufferableMethods; } else { bufferableMethods = inherited; Bufferable._canonicalize(bufferableMethods); proto.bufferables = null; } if (bufferableMethods) { for (name in bufferableMethods) { if (!proto[name]) { def = bufferableMethods[name]; Bufferable.processMethod(proto, def, Array.prototype.slice); } } } }, processMethod: function(proto, def, slice) { var name = def.name, cap = def.capitalized; proto[name] = function() { return Bufferable.delayCall(this, def, slice.call(arguments)); }; proto['cancel' + cap] = function() { return this.cancelBufferedCall(name); }; proto['flush' + cap] = function() { return this.flushBufferedCall(name); }; } } } }; }); Ext.define('Ext.ComponentManager', { alternateClassName: 'Ext.ComponentMgr', singleton: true, mixins: [ Ext.mixin.Bufferable ], count: 0, referencesDirty: true, referenceRepairs: 0, typeName: 'xtype', bufferableMethods: { handleDocumentMouseDown: 'asap' }, constructor: function(config) { var me = this; Ext.apply(me, config); me.all = {}; me.byInstanceId = {}; me.holders = {}; me.names = {}; 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, id = component.getId(), onAvailableCallbacks = me.onAvailableCallbacks; if (id === undefined) { Ext.raise('Component id is undefined. Please ensure the component has an id.'); } if (id in me.all) { Ext.raise('Duplicate component id "' + id + '"'); } if (component.$iid in me.byInstanceId) { Ext.raise('Duplicate component instance id "' + component.$iid + '"'); } me.all[id] = component; me.byInstanceId[component.$iid] = component; if (component.reference) { me.references[id] = component; } if (component.name && component.nameable) { me.names[id] = component; } if (component.nameHolder || component.referenceHolder) { me.holders[id] = component; } ++me.count; if (!me.hasFocusListener) { me.installFocusListener(); } onAvailableCallbacks = onAvailableCallbacks && onAvailableCallbacks[id]; if (onAvailableCallbacks && onAvailableCallbacks.length) { me.notifyAvailable(component); } }, unregister: function(component) { var me = this, all = me.all, byInstanceId = me.byInstanceId, holders = me.holders, references = me.references, names = me.names, id = component.getId(); if (id in holders) { holders[id] = null; delete holders[id]; } if (id in names) { names[id] = null; delete names[id]; } if (id in references) { references[id] = null; delete references[id]; } all[id] = null; delete all[id]; id = component.$iid; byInstanceId[id] = null; delete byInstanceId[id]; --me.count; }, markReferencesDirty: function() { var me = this, holders = me.holders, key; if (!me.referencesDirty) { for (key in holders) { holders[key].refs = holders[key].nameRefs = null; } me.referencesDirty = true; } }, fixReferences: function() { var me = this, references = me.references, names = me.names, key; if (me.referencesDirty) { ++me.referenceRepairs; for (key in references) { references[key]._fixReference(); } for (key in names) { names[key]._fixName(); } 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) { 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.from(Ext.dom.Element.getActiveElement()); }, onGlobalFocus: function(e) { var me = this, event = e.event, toComponent = event.toComponent = e.toComponent = Ext.Component.from(e.toElement), fromComponent = event.fromComponent = e.fromComponent = Ext.Component.from(e.fromElement), commonAncestor = me.getCommonAncestor(fromComponent, toComponent), targetComponent; if (toComponent !== fromComponent) { if (fromComponent && !fromComponent.destroyed && !fromComponent.isDestructing()) { if (fromComponent.handleBlurEvent) { fromComponent.handleBlurEvent(e); } for (targetComponent = fromComponent; targetComponent && targetComponent !== commonAncestor; targetComponent = targetComponent.getRefOwner()) { if (!(targetComponent.destroyed || targetComponent.destroying)) { e.type = 'focusleave'; targetComponent.onFocusLeave(event); } } } if (toComponent && !toComponent.destroyed && !toComponent.isDestructing()) { if (toComponent.handleFocusEvent) { toComponent.handleFocusEvent(e); } for (targetComponent = toComponent; targetComponent && targetComponent !== commonAncestor; targetComponent = targetComponent.getRefOwner()) { e.type = 'focusenter'; targetComponent.onFocusEnter(event); } } } for (targetComponent = commonAncestor; targetComponent; targetComponent = targetComponent.getRefOwner()) { if (!(targetComponent.destroying || targetComponent.destroyed)) { targetComponent.onFocusMove(e); } } }, getCommonAncestor: function(compA, compB) { if (compA === compB) { return compA; } while (compA && !(compA.isAncestor(compB) || compA === compB)) { compA = compA.getRefOwner(); } return compA; }, privates: { doHandleDocumentMouseDown: function(e) { var floatedSelector = Ext.Widget.prototype.floatedSelector, targetFloated; if (floatedSelector) { targetFloated = Ext.Component.from(e.getTarget(floatedSelector, Ext.getBody())); if (targetFloated) { targetFloated.toFront(true); } } }, installFocusListener: function() { var me = this; Ext.on('focus', me.onGlobalFocus, me); me.hasFocusListener = true; }, clearAll: function() { this.all = {}; this.names = {}; this.references = {}; this.onAvailableCallbacks = {}; }, from: function(el, limit, selector) { if (el && el.isEvent) { el = el.target; } var target = Ext.getDom(el), cache = this.all, depth = 0, topmost, cmpId, cmp; if (typeof limit !== 'number') { topmost = Ext.getDom(limit); limit = Number.MAX_VALUE; } while (target && target.nodeType === 1 && depth < limit && target !== topmost) { cmpId = target.getAttribute('data-componentid') || target.id; if (cmpId) { cmp = cache[cmpId]; if (cmp && (!selector || Ext.ComponentQuery.is(cmp, selector))) { return cmp; } depth++; } target = target.parentNode; } return null; } } }, function() { var ComponentManager = Ext.ComponentManager; ComponentManager.fromElement = ComponentManager.from; Ext.getCmp = function(id) { return ComponentManager.get(id); }; Ext.iidToCmp = function(iid) { return ComponentManager.byInstanceId[iid] || null; }; Ext.doEv = function(node, e) { var cmp, method, event; cmp = Ext.Component.from(e.target); if (cmp && !cmp.destroying && !cmp.destroyed && cmp.getEventHandlers) { method = cmp.getEventHandlers()[e.type]; if (method && cmp[method]) { event = new Ext.event.Event(e); return cmp[method](event); } } return true; }; }); 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([ initial ]); }, 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 }, 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.destroyed && 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 && candidate.self.getConfigurator && 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 ? !!propValue : queryOperators[operator](Ext.coerce(propValue, compareTo), compareTo)) { result.push(candidate); } } return result; }, filterById = function(items, id, idOnly) { var result = [], i = 0, length = items.length, candidate, check; for (; i < length; i++) { candidate = items[i]; check = idOnly ? candidate.id : candidate.getItemId(); if (check === 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, root) { 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, root, op); if (result) { return result; } } return false; }, _is: function(component, root, 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); } } else { active = filterItems(active, operation); } if (active.length === 0) { return false; } } if (root) { if (!mode) { active = getAncestors(active); } if (active.length > 0) { active = filterItems(active, { method: filterById, args: [ root.id, true ] }); } 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; }, canfocus: function(cmps, value) { var len = cmps.length, results = [], i = 0, c; for (; i < len; i++) { c = cmps[i]; if (c.canFocus && c.canFocus(false, value)) { 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; }, scrollable: function(cmps) { var len = cmps.length, results = [], i = 0, c; for (; i < len; i++) { c = cmps[i]; if (c.scrollable || c._scrollable) { results.push(c); } } return results; }, visible: function(cmps, deep) { deep = deep === 'true'; var len = cmps.length, results = [], i = 0, c; for (; i < len; i++) { c = cmps[i]; if (c.isVisible(deep)) { results.push(c); } } return results; } }, query: function(selector, root) { if (!selector) { return Ext.ComponentManager.getAll(); } 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, root) { if (!selector) { return true; } if (typeof selector === 'function') { return selector(component); } else { var query = cq.cache.get(selector); if (!query) { query = cq.cache.add(selector, cq.parse(selector)); } return query.is(component, root); } }, 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.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.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.all = function() { return cq.query.apply(cq, arguments); }; Ext.first = function() { var matches = cq.query.apply(cq, arguments); return (matches && matches[0]) || null; }; }); Ext.define('Ext.Evented', { alternateClassName: 'Ext.EventedBase', mixins: [ Ext.mixin.Observable ], initialized: false, constructor: function(config) { this.callParent(); this.mixins.observable.constructor.call(this, config); this.initialized = true; }, onClassExtended: function(cls, data) { if (!data.hasOwnProperty('eventedConfig')) { return; } var config = data.config, eventedConfig = data.eventedConfig, 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.eventedSetter || cfg.getEventedSetter(); } } } }); Ext.define('Ext.util.Positionable', { mixinId: 'positionable', _positionTopLeft: [ 'position', 'top', 'left' ], clippedCls: Ext.baseCSSPrefix + 'clipped', afterSetPosition: Ext.emptyFn, getAnchorToXY: function() { Ext.raise("getAnchorToXY is not implemented in " + this.$className); }, getBorderPadding: function() { Ext.raise("getBorderPadding is not implemented in " + this.$className); }, getLocalX: function() { Ext.raise("getLocalX is not implemented in " + this.$className); }, getLocalXY: function() { Ext.raise("getLocalXY is not implemented in " + this.$className); }, getLocalY: function() { Ext.raise("getLocalY is not implemented in " + this.$className); }, getX: function() { Ext.raise("getX is not implemented in " + this.$className); }, getXY: function() { Ext.raise("getXY is not implemented in " + this.$className); }, getY: function() { Ext.raise("getY is not implemented in " + this.$className); }, setLocalX: function() { Ext.raise("setLocalX is not implemented in " + this.$className); }, setLocalXY: function() { Ext.raise("setLocalXY is not implemented in " + this.$className); }, setLocalY: function() { Ext.raise("setLocalY is not implemented in " + this.$className); }, setX: function() { Ext.raise("setX is not implemented in " + this.$className); }, setXY: function() { Ext.raise("setXY is not implemented in " + this.$className); }, setY: function() { Ext.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, size) { var region = this.getRegion(); region.setPosition(0, 0); region.translateBy(extraX || 0, extraY || 0); if (size) { region.setWidth(size.width); region.setHeight(size.height); } return region.getAnchorPoint(anchor); }, convertPositionSpec: function(posSpec) { return Ext.util.Region.getAlignInfo(posSpec); }, getAlignToXY: function(alignToEl, position, offsets) { var newRegion = this.getAlignToRegion(alignToEl, position, offsets); return [ newRegion.x, newRegion.y ]; }, getAlignToRegion: function(alignToEl, posSpec, offset, minHeight) { var me = this, inside, newRegion, bodyScroll; alignToEl = Ext.fly(alignToEl.el || alignToEl); if (!alignToEl || !alignToEl.dom) { Ext.raise({ sourceClass: 'Ext.util.Positionable', sourceMethod: 'getAlignToXY', msg: 'Attempted to align an element that doesn\'t exist' }); } posSpec = me.convertPositionSpec(posSpec); if (posSpec.constrain) { if (posSpec.constrain === '!') { inside = alignToEl; } else { inside = me.constrainTo || me.container || me.el.parent(); } inside = Ext.fly(inside.el || inside).getConstrainRegion(); } if (alignToEl === Ext.getBody()) { bodyScroll = alignToEl.getScroll(); offset = [ bodyScroll.left, bodyScroll.top ]; } newRegion = me.getRegion().alignTo({ target: alignToEl.getRegion(), inside: inside, minHeight: minHeight, offset: offset, align: posSpec, axisLock: true }); return newRegion; }, getAnchorXY: function(anchor, local, size) { var me = this, region = me.getRegion(), el = me.el, isViewport = el.dom.nodeName === 'BODY' || el.dom.nodeType === 9, scroll = el.getScroll(); if (local) { region.setPosition(0, 0); } else if (isViewport) { region.setPosition(scroll.left, scroll.top); } if (size) { region.setWidth(size.width); region.setHeight(size.height); } return region.getAnchorPoint(anchor); }, getBox: function(contentBox, local) { var me = this, xy = local ? me.getLocalXY() : me.getXY(), x = xy[0], y = xy[1], w, h, borderPadding, beforeX, beforeY; if (me.el.dom.nodeName === 'BODY' || me.el.dom.nodeType === 9) { w = Ext.Element.getViewportWidth(); h = Ext.Element.getViewportHeight(); } else { w = me.getWidth(); h = me.getHeight(); } 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; 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 me = this, thisRegion = me.getRegion(), vector = [ 0, 0 ], shadowSize = (me.shadow && me.constrainShadow && !me.shadowDisabled) ? me.el.shadow.getShadowSize() : undefined, overflowed = false, constraintInsets = me.constraintInsets; if (!(constrainTo instanceof Ext.util.Region)) { constrainTo = Ext.get(constrainTo.el || constrainTo); constrainTo = constrainTo.getConstrainRegion(); } if (constraintInsets) { constraintInsets = Ext.isObject(constraintInsets) ? constraintInsets : Ext.Element.parseBox(constraintInsets); constrainTo.adjust(constraintInsets.top, constraintInsets.right, constraintInsets.bottom, constraintInsets.left); } 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 = offsetsTo.isRegion ? [ offsetsTo.x, offsetsTo.y ] : Ext.fly(offsetsTo.el || offsetsTo).getXY(); return [ o[0] - e[0], o[1] - e[1] ]; }, getRegion: function(contentBox, local) { var box = this.getBox(contentBox, local); return new Ext.util.Region(box.top, box.right, box.bottom, box.left); }, getClientRegion: function() { var me = this, el = me.el, dom = el.dom, viewContentBox = me.getBox(true), scrollbarHeight = dom.offsetHeight > dom.clientHeight, scrollbarWidth = dom.offsetWidth > dom.clientWidth, padding, scrollSize, isRTL; if (scrollbarHeight || scrollbarWidth) { scrollSize = Ext.getScrollbarSize(); if (scrollbarWidth) { scrollbarWidth = scrollSize.width; isRTL = el.getStyle('direction') === 'rtl' && !Ext.supports.rtlVertScrollbarOnRight; if (isRTL) { padding = el.getPadding('l'); viewContentBox.left -= padding + Math.max(padding, scrollbarWidth); } else { padding = el.getPadding('r'); viewContentBox.right += padding - Math.max(padding, scrollbarWidth); } } if (scrollbarHeight) { scrollbarHeight = scrollSize.height; padding = el.getPadding('b'); viewContentBox.bottom += padding - Math.max(padding, scrollbarHeight); } } return new Ext.util.Region(viewContentBox.top, viewContentBox.right, viewContentBox.bottom, viewContentBox.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, 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; }, privates: { clipTo: function(clippingEl, sides) { var clippingRegion, el = this.el, floaterRegion = el.getRegion(), overflow, i, clipValues = [], clippedCls = this.clippedCls, clipStyle, clipped, shadow; if (clippingEl.isRegion) { clippingRegion = clippingEl; } else { clippingRegion = (clippingEl.isComponent ? clippingEl.el : Ext.fly(clippingEl)).getConstrainRegion(); } if (!sides) { sides = 15; } if (sides & 1 && (overflow = clippingRegion.top - floaterRegion.top) > 0) { clipValues[0] = overflow; clipped = true; } else { clipValues[0] = -10000; } if (sides & 2 && (overflow = floaterRegion.right - clippingRegion.right) > 0) { clipValues[1] = Math.max(0, el.getWidth() - overflow); clipped = true; } else { clipValues[1] = 10000; } if (sides & 4 && (overflow = floaterRegion.bottom - clippingRegion.bottom) > 0) { clipValues[2] = Math.max(0, el.getHeight() - overflow); clipped = true; } else { clipValues[2] = 10000; } if (sides & 8 && (overflow = clippingRegion.left - floaterRegion.left) > 0) { clipValues[3] = overflow; clipped = true; } else { clipValues[3] = -10000; } clipStyle = 'rect('; for (i = 0; i < 4; ++i) { clipStyle += Ext.Element.addUnits(clipValues[i], 'px'); clipStyle += (i === 3) ? ')' : ','; } el.dom.style.clip = clipStyle; el.addCls(clippedCls); if ((shadow = el.shadow) && (el = shadow.el) && el.dom) { clipValues[2] -= shadow.offsets.y; clipValues[3] -= shadow.offsets.x; clipStyle = 'rect('; for (i = 0; i < 4; ++i) { clipStyle += Ext.Element.addUnits(clipValues[i], 'px'); clipStyle += (i === 3) ? ')' : ','; } el.dom.style.clip = clipStyle; if (clipped && !Ext.supports.CSS3BoxShadow) { el.dom.style.display = 'none'; } else { el.dom.style.display = ''; el.addCls(clippedCls); } } }, clearClip: function() { var el = this.el, clippedCls = this.clippedCls; el.dom.style.clip = Ext.isIE8 ? 'auto' : ''; el.removeCls(clippedCls); if (el.shadow && el.shadow.el && el.shadow.el.dom) { el.shadow.el.dom.style.clip = Ext.isIE8 ? 'auto' : ''; if (!Ext.supports.CSS3BoxShadow) { el.dom.style.display = ''; el.removeCls(clippedCls); } } } } }); 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); Ext.getDetachedBody().dom.appendChild(el.dom); }, reset: function() { var cache = this.cache, i = cache.length; while (i--) { cache[i].destroy(); } this.cache = []; } }); Ext.define('Ext.dom.Underlay', { 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) { if (el.dom) { 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, isDirectEvent = Ext.event.publisher.Dom.instance.directEvents[name], captures, directs, directCaptures; options = options || {}; if (options.delegated === false || isDirectEvent) { if (isDirectEvent && options.delegate) { options.capture = true; } 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', { isEventPublisher: true, $vetoClearingPrototypeOnDestroy: true, handledEvents: [], statics: { publishers: {}, publishersByEvent: {} }, constructor: function() { var me = this, type = me.type; me.handles = {}; if (!type) { Ext.raise("Event publisher '" + me.$className + "' defined without a 'type' property."); } if (me.self.instance) { Ext.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; } }, subscribe: function() { Ext.raise("Ext.event.publisher.Publisher subclass '" + this.$className + '" has no subscribe method.'); }, unsubscribe: function() { Ext.raise("Ext.event.publisher.Publisher subclass '" + this.$className + '" has no unsubscribe method.'); }, fire: function(element, eventName, args) { var event; if (element.hasListeners[eventName]) { event = element.events[eventName]; if (event) { event.fire.apply(event, args); } } } }); Ext.define('Ext.util.Offset', { statics: { fromObject: function(obj) { if (obj instanceof this) { return obj; } if (typeof obj === 'number') { return new this(obj, obj); } if (obj.length) { return new this(obj[0], obj[1]); } 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.raise('Offset must be an instance of Ext.util.Offset'); } return (this.x === offset.x && this.y === offset.y); }, add: function(offset) { if (!(offset instanceof this.statics())) { Ext.raise('Offset must be an instance of Ext.util.Offset'); } 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', function() { var ExtUtil = Ext.util, constrainRe = /([^\?!]*)(!|\?)?$/, alignRe = /^(?:(?:([trbl])(\d+))|(tl|t|tc|tr|l|c|r|bl|b|bc|br))(?:-(?:(?:([trbl])(\d+))|(tl|t|tc|tr|l|c|r|bl|b|bc|br)))?$/i, LTROffsetFactors = { l: 0, r: 100, t: 0, b: 100, c: 50 }, RTLOffsetFactors = { l: 100, r: 0, t: 0, b: 100, c: 50 }, relativePositions = { b: 0, l: 1, t: 2, r: 3 }, alignMap = { "tl-tr": "l0-r0", "tl-r": "l0-r50", "bl-r": "l100-r50", "bl-br": "l100-r100", "tr-tl": "r0-l0", "tr-l": "r0-l50", "br-l": "r100-l50", "br-bl": "r100-l100" }, rtlAlignMap = { "tl-tr": "r0-l0", "tl-r": "r0-l50", "bl-r": "r100-l50", "bl-br": "r100-l100", "tr-tl": "l0-r0", "tr-l": "l0-r50", "br-l": "l100-r50", "br-bl": "l100-r100" }, adjustParams = [], zeroOffset = new ExtUtil.Offset(0, 0), parseRegion = function(box) { var Region = ExtUtil.Region, type = typeof box, top, right, bottom, left; if (box == null) { return Region.EMPTY; } if (box.isRegion) { return box; } if (box.isElement || box.nodeType === 1) { return this.getRegion(box); } if (type === 'string') { box = box.split(' '); switch (box.length) { case 1: box[1] = box[2] = box[3] = box[0]; break; case 2: box[2] = box[0]; box[3] = box[1]; break; case 3: box[3] = box[1]; } top = parseInt(box[0], 10) || 0; right = parseInt(box[1], 10) || 0; bottom = parseInt(box[2], 10) || 0; left = parseInt(box[3], 10) || 0; } else if (type === 'number') { top = right = bottom = left = box; } else if (typeof box.x === 'number') { top = box.y; left = box.x; if (typeof box.right === 'number') { right = box.right; bottom = box.bottom; } else { right = left + box.width; bottom = top + box.height; } } else { Ext.raise('Not convertible to a Region: ' + box); } return new Region(top, right, bottom, left); }, magnitude = [ -1, 1, 1, -1 ], addAnchorOffset = function(target, anchorSize, relativePosition) { if (relativePosition != null && anchorSize) { adjustParams[0] = adjustParams[1] = adjustParams[2] = adjustParams[3] = 0; adjustParams[relativePosition] = anchorSize.y * magnitude[relativePosition]; target = ExtUtil.Region.from(target); target.adjust.apply(target, adjustParams); } return target; }, calculateAnchorPosition = function(target, result, relativePosition, anchorSize, inside) { var anchorWidth = Math.ceil(anchorSize.x), minOverlap = Math.ceil(anchorWidth / 2) + 3, min, max, anchorPos, isBefore, overlapLine, x, y; if (inside && !inside.intersect(target)) { return; } if (relativePosition != null) { if (relativePosition & 1) { if (result.getHeight() < anchorWidth + 4) { return; } min = target.top + minOverlap - result.height; max = target.bottom - minOverlap - 1; result.setPosition(result.x, Math.min(Math.max(result.y, min), max)); min = result.top + 2; max = result.bottom - (anchorWidth + 2); isBefore = relativePosition === 3; x = isBefore ? result.right : result.left; overlapLine = new ExtUtil.Region(Math.max(result.top, target.top), x, Math.min(result.bottom, target.bottom), x); anchorPos = new ExtUtil.Region(0, 0, 0, 0).setWidth(anchorSize.y).setHeight(anchorWidth).alignTo({ target: overlapLine, align: isBefore ? 'l-r' : 'r-l', overlap: true }); anchorPos.setPosition(anchorPos.x, Math.min(Math.max(anchorPos.y, min), max)); anchorPos.position = isBefore ? 'right' : 'left'; } else { if (result.getWidth() < anchorWidth + 4) { return; } min = target.left + minOverlap - result.width; max = target.right - minOverlap - 1; result.setPosition(Math.min(Math.max(result.x, min), max), result.y); min = result.left + 2; max = result.right - (anchorWidth + 2); isBefore = relativePosition === 0; y = isBefore ? result.bottom : result.top; overlapLine = new ExtUtil.Region(y, Math.min(result.right, target.right), y, Math.max(result.left, target.left)); anchorPos = new ExtUtil.Region(0, 0, 0, 0).setWidth(anchorWidth).setHeight(anchorSize.y).alignTo({ target: overlapLine, align: isBefore ? 't-b' : 'b-t', overlap: true }); anchorPos.setPosition(Math.min(Math.max(anchorPos.x, min), max), anchorPos.y); anchorPos.position = isBefore ? 'bottom' : 'top'; } if (inside && !inside.contains(anchorPos)) { return; } result.anchor = anchorPos; result.anchor.align = relativePosition; } }, checkMinHeight = function(minHeight, result, target, inside) { var newHeight; if (minHeight && inside) { if (result.top >= target.bottom && result.bottom > inside.bottom) { result.setHeight(Math.max(result.getHeight() + inside.bottom - result.bottom, minHeight)); result.constrainHeight = true; } else if (result.bottom <= target.top && result.top < inside.top) { newHeight = Math.max(result.getHeight() + result.top - inside.top, minHeight); result.adjust(result.getHeight() - newHeight); result.constrainHeight = true; } else if (result.getHeight() > inside.getHeight()) { result.setHeight(Math.max(minHeight, inside.getHeight())); result.setPosition(result.x, 0); result.constrainHeight = true; } } }, checkMinWidth = function(minWidth, result, target, inside) { var newWidth; if (minWidth && inside) { if (result.left >= target.right && result.right > inside.right) { result.setWidth(Math.max(result.getWidth() + inside.right - result.right, minWidth)); result.constrainWidth = true; } else if (result.right <= target.left && result.left < inside.left) { newWidth = Math.max(result.getWidth() + result.left - inside.left, minWidth); result.adjust(0, 0, 0, result.getWidth() - newWidth); result.constrainWidth = true; } else if (result.getWidth() > inside.getWidth()) { result.setWidth(Math.max(minWidth, inside.getWidth())); result.setPosition(0, result.y); result.constrainWidth = true; } } }; return { 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); }, getAlignInfo: function(align, rtl) { if (typeof align === 'object') { return align; } align = align ? ((align.indexOf('-') < 0) ? 'tl-' + align : align) : 'tl-bl'; constrain = constrainRe.exec(align); align = constrain[1]; align = (rtl ? rtlAlignMap : alignMap)[align] || align; var offsetFactors = rtl ? RTLOffsetFactors : LTROffsetFactors, constrain, parts = alignRe.exec(align), result; if (!parts) { Ext.raise({ sourceClass: 'Ext.util.Region', sourceMethod: 'getAlignInfo', position: align, msg: 'Attempted to align an element with an invalid position: "' + align + '"' }); } result = { myEdge: parts[1], myOffset: parts[2], otherEdge: parts[4], otherOffset: parts[5], constrain: constrain[2] }; if (parts[3]) { result.myEdge = parts[3][0]; result.myOffset = offsetFactors[parts[3][1]]; if (result.myOffset == null) { result.myOffset = 50; } } if (parts[6]) { result.otherEdge = parts[6][0]; result.otherOffset = offsetFactors[parts[6][1]]; if (result.otherOffset == null) { result.otherOffset = 50; } } result.position = relativePositions[result.myEdge]; return result; } }, constructor: function(top, right, bottom, left) { var me = this; me.y = me.top = me[1] = top; me.right = right; me.bottom = bottom; me.x = me.left = me[0] = left; me.height = me.bottom - me.top; me.width = me.right - me.left; }, setPosition: function(x, y) { if (arguments.length === 1) { y = x[1]; x = x[0]; } return this.translateBy(x - this.x, y - this.y); }, contains: function(region) { var me = this; return (region.x >= me.x && (region.right || region.x) <= me.right && region.y >= me.y && (region.bottom || region.y) <= 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(targetRegion) { var me = this, constrain = Ext.Number.constrain; me.top = me.y = constrain(me.top, targetRegion.y, targetRegion.bottom); me.bottom = constrain(me.bottom, targetRegion.y, targetRegion.bottom); me.left = me.x = constrain(me.left, targetRegion.x, targetRegion.right); me.right = constrain(me.right, targetRegion.x, targetRegion.right); me.height = me.bottom - me.top; me.width = me.right - me.left; return me; }, adjust: function(top, right, bottom, left) { var me = this; me.top = me.y += top || 0; me.left = me.x += left || 0; me.right += right || 0; me.bottom += bottom || 0; me.height = me.bottom - me.top; me.width = me.right - me.left; 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 ExtUtil.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; }, alignTo: function(options) { var me = this, Region = me.self, Offset = ExtUtil.Offset, Element = Ext.Element, target = parseRegion(options.target), targetPlusAnchorOffset, rtl = options.rtl, overlap = options.overlap, align = options.align, anchorSize = options.anchorSize, offset = options.offset, inside = options.inside, position = options.position, allowXTranslate = options.allowXTranslate, allowYTranslate = options.allowYTranslate, wasConstrained, result, initialPosition, constrainedPosition; if (offset) { offset = Offset.fromObject(offset); if (!(offset instanceof Offset)) { Ext.raise('offset option must be an Ext.util.Offset'); } } if (anchorSize) { anchorSize = Offset.fromObject(anchorSize); if (!(anchorSize instanceof Offset)) { Ext.raise('anchorSize option must be an Ext.util.Offset'); } } if (inside && !inside.isRegion) { if (Ext.getDom(inside) === document.body) { inside = new Region(0, Element.getDocumentWidth(), Element.getDocumentHeight(), 0); } else { inside = Ext.fly(inside).getRegion(); } } if (position) { if (position.length === 2) { position = new ExtUtil.Point(position[0], position[1]); } result = new Region().copyFrom(me).setPosition(position.x, position.y); } else { align = me.getAlignInfo(align, rtl); if (inside) { if (target.x >= inside.right) { target.setPosition(inside.right - 1, target.y); if (align.position !== 3) { align = me.getAlignInfo('r-l', rtl); } } else if (target.right < inside.x) { target.setPosition(inside.x - target.getWidth() + 1, target.y); if (align.position !== 1) { align = me.getAlignInfo('l-r', rtl); } } if (target.y >= inside.bottom) { target.setPosition(target.x, inside.bottom - 1); if (align.position !== 0) { align = me.getAlignInfo('b-t', rtl); } } else if (target.bottom < inside.y) { target.setPosition(target.x, inside.y - target.getHeight() + 1); if (align.position !== 2) { align = me.getAlignInfo('t-b', rtl); } } } targetPlusAnchorOffset = anchorSize ? addAnchorOffset(target, anchorSize, align.position) : target; result = Region.from(me).translateBy(me.getAlignToVector(targetPlusAnchorOffset, align)); overlap = !!result.intersect(targetPlusAnchorOffset); if (offset && (overlap || !anchorSize)) { result.translateBy(offset); } if (anchorSize) { calculateAnchorPosition(target, result, align.position, anchorSize, inside); } } if (inside) { initialPosition = result.copy(); if (result.left < inside.left) { result.translateBy(inside.left - result.left, 0); wasConstrained = true; } if (result.right > inside.right && result.left > inside.left) { result.translateBy(inside.right - result.right, 0); wasConstrained = true; } if (result.top < inside.top) { result.translateBy(0, inside.top - result.top); wasConstrained = true; } if (result.bottom > inside.bottom && result.top > inside.top) { result.translateBy(0, inside.bottom - result.bottom); wasConstrained = true; } if (wasConstrained && !overlap) { result.anchor = null; if (options.axisLock) { if (align.position & 1) { allowYTranslate = false; } else { allowXTranslate = false; } } if (position) { if (result.contains(position)) { position.exclude(result, { inside: inside, centerOnSideChange: false }); } } else { constrainedPosition = result.copy(); if (result.intersect(targetPlusAnchorOffset)) { align.position = target.exclude(result, { initialPosition: initialPosition, defaultPosition: align.position, inside: inside, minHeight: options.minHeight, minWidth: options.minWidth, allowX: allowXTranslate, allowY: allowYTranslate, offset: offset, anchorHeight: anchorSize ? anchorSize.y : 0, centerOnSideChange: !!anchorSize }); } else if (options.minWidth && result.getWidth() > inside.getWidth()) { result.setPosition(0, result.y); result.setWidth(Math.max(inside.getWidth(), options.minWidth)); result.constrainWidth = true; } else if (options.minHeight && result.getHeight() > inside.getHeight()) { result.setPosition(result.x, 0); result.setHeight(Math.max(inside.getHeight(), options.minHeight)); result.constrainHeight = true; } result.align = align; if (inside.contains(result)) { if (anchorSize) { calculateAnchorPosition(target, result, align.position, anchorSize, inside); } } else { result = constrainedPosition; } } } } return result; }, exclude: function(other, options) { options = options || {}; var me = this, initialPosition = options.initialPosition || other, inside = options.inside, defaultPosition = options.defaultPosition, centerOnSideChange = options.centerOnSideChange, minHeight = options.minHeight, minWidth = options.minWidth, allowX = options.allowX !== false, allowY = options.allowY !== false, anchorHeight = options.anchorHeight, offset = options.offset, translations = [], testRegion, t, i, sizeConstrainedSolution, leastBadSolution, intersection, result; if (!offset) { offset = zeroOffset; } if (allowY) { translations.push([ 0, me.top - other.bottom - anchorHeight + offset.y, 'b-t', 0, Math.abs(me.top - initialPosition.bottom - anchorHeight + offset.y) ]); translations.push([ 0, me.bottom - other.top + anchorHeight + offset.y, 't-b', 2, Math.abs(me.bottom - initialPosition.top + anchorHeight + offset.y) ]); } else { centerOnSideChange = false; } if (allowX) { translations.push([ me.left - other.right - anchorHeight + offset.x, 0, 'r-l', 3, Math.abs(me.left - initialPosition.right - anchorHeight + offset.x) ]); translations.push([ me.right - other.left + anchorHeight + offset.x, 0, 'l-r', 1, Math.abs(me.right - initialPosition.left + anchorHeight + offset.x) ]); } else { centerOnSideChange = false; } Ext.Array.sort(translations, function(l, r) { var result = l[4] - r[4]; if (!result) { if (l[3] === defaultPosition) { return -1; } if (r[3] === defaultPosition) { return 1; } } return result; }); if (inside) { for (i = 0; i < translations.length; i++) { t = translations[i]; testRegion = ExtUtil.Region.from(other); testRegion.translateBy.apply(testRegion, t); if (inside.contains(testRegion)) { other.copyFrom(testRegion); result = { align: t[2], position: t[3], distance: t[4] }; break; } if (minHeight) { checkMinHeight(minHeight, testRegion, me, inside); if (inside.contains(testRegion)) { if (!sizeConstrainedSolution || testRegion.getArea() > sizeConstrainedSolution.region.getArea()) { sizeConstrainedSolution = { region: testRegion, align: t[2], position: t[3], distance: t[4] }; } } } if (minWidth) { checkMinWidth(minWidth, testRegion, me, inside); if (inside.contains(testRegion)) { if (!sizeConstrainedSolution || testRegion.getArea() > sizeConstrainedSolution.region.getArea()) { sizeConstrainedSolution = { region: testRegion, align: t[2], position: t[3], distance: t[4] }; } } } intersection = inside.intersect(testRegion); if (intersection) { intersection = intersection.getArea(); if (!leastBadSolution || (intersection && leastBadSolution.area < intersection)) { leastBadSolution = { region: testRegion, align: t[2], position: t[3], distance: t[4], area: intersection }; } } } if (!result) { if (sizeConstrainedSolution) { other.copyFrom(sizeConstrainedSolution.region); result = sizeConstrainedSolution; other.constrainWidth = sizeConstrainedSolution.region.constrainWidth; other.constrainHeight = sizeConstrainedSolution.region.constrainHeight; } else if (leastBadSolution) { other.copyFrom(leastBadSolution.region); result = leastBadSolution; } } if (result) { if ((result.position & 1) !== (defaultPosition & 1)) { if (result.distance && centerOnSideChange) { t = other.alignTo({ align: result.align, target: me, anchorSize: anchorHeight, offset: offset, axisLock: true, inside: inside, minHeight: options.minHeight, minWidth: options.minWidth }); if (inside.contains(t)) { other.setPosition(t.x, t.y); } } } return result.position; } } else { other.translateBy.apply(other, translations[0]); return translations[0][3]; } return defaultPosition; }, getAlignToXY: function(target, align, rtl) { var alignVector = this.getAlignToVector(target, align, rtl); return [ this.x + alignVector[0], this.y + alignVector[1] ]; }, getAnchorPoint: function(align, rtl) { align = (typeof align === 'string') ? this.getAlignInfo(align + '-tl', rtl) : align; return this['getAnchorPoint_' + align.myEdge](align.myOffset); }, getAlignToVector: function(target, align, rtl) { align = (typeof align === 'string') ? this.getAlignInfo(align, rtl) : align; var myAnchorPoint = this['getAnchorPoint_' + align.myEdge](align.myOffset), targetAnchorPoint = target['getAnchorPoint_' + align.otherEdge](align.otherOffset); return [ targetAnchorPoint[0] - myAnchorPoint[0], targetAnchorPoint[1] - myAnchorPoint[1] ]; }, getAnchorPoint_t: function(offset) { return [ this.x + Math.round(this.getWidth() * (offset / 100)), this.y ]; }, getAnchorPoint_b: function(offset) { return [ this.x + Math.round(this.getWidth() * (offset / 100)), this.bottom ]; }, getAnchorPoint_l: function(offset) { return [ this.x, this.y + Math.round(this.getHeight() * (offset / 100)) ]; }, getAnchorPoint_r: function(offset) { return [ this.right, this.y + Math.round(this.getHeight() * (offset / 100)) ]; }, getAnchorPoint_c: function() { return [ this.x + Math.round(this.getWidth() / 2), this.y + Math.round(this.getHeight() / 2) ]; }, getCenter: function() { return [ this.x + this.width / 2, this.y + this.height / 2 ]; }, getHeight: function() { return this.bottom - this.y; }, getWidth: function() { return this.right - this.x; }, getArea: function() { return this.getHeight() * this.getWidth(); }, setHeight: function(h) { this.height = h; this.bottom = this.top + h; return this; }, setWidth: function(w) { this.width = w; this.right = this.left + w; return this; }, getSize: function() { return { width: this.right - this.x, height: this.bottom - this.y }; }, setSize: function(w, h) { if (h === undefined) { h = w; } this.setWidth(w); return this.setHeight(h); }, 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 me; }, toString: function() { return "Region[" + this.top + "," + this.right + "," + this.bottom + "," + this.left + "]"; }, translateBy: function(x, y) { if (x.length) { y = x[1]; x = x[0]; } else 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); }, getOffsetsTo: function(offsetsTo) { return { x: this.x - offsetsTo.x, y: this.y - offsetsTo.y }; }, highlight: function() { var highlightEl = Ext.getBody().createChild({ style: 'background-color:#52a0db;opacity:0.4;position:absolute;z-index:9999999' }); highlightEl.setBox(this); Ext.defer(function() { highlightEl.destroy(); }, 5000); return highlightEl; } }; }, function(Region) { Region.prototype.getAlignInfo = Region.getAlignInfo; Region.EMPTY = new Region(0, 0, 0, 0); if (Object.freeze) { Object.freeze(Region.EMPTY); } }); Ext.define('Ext.util.Point', { extend: Ext.util.Region, isPoint: true, 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 + "]"; }, equals: function(point) { return (this.x === point.x && this.y === point.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', stopped: false, claimed: false, defaultPrevented: false, isEvent: true, geckoRelatedTargetEvents: { blur: 1, dragenter: 1, dragleave: 1, focus: 1 }, statics: { resolveTextNode: function(node) { return (node && node.nodeType === 3) ? node.parentNode : node; }, gestureEvents: {}, 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, focusin: 1, focusenter: 1 }, blurEvents: { blur: 1, focusout: 1, focusleave: 1 }, pointerTypeMap: { 2: 'touch', 3: 'pen', 4: 'mouse', touch: 'touch', pen: 'pen', mouse: 'mouse' }, keyEventRe: /^key/, keyFlags: { CTRL: 'ctrlKey', CONTROL: 'ctrlKey', ALT: 'altKey', SHIFT: 'shiftKey', CMD: 'metaKey', COMMAND: 'metaKey', CMDORCTRL: Ext.isMac ? 'metaKey' : 'ctrlKey', COMMANDORCONTROL: Ext.isMac ? 'metaKey' : 'ctrlKey', META: 'metaKey' }, modifierGlyphs: { ctrlKey: '⌃', altKey: '⌥', metaKey: Ext.isMac ? '⌘' : '⊞', shiftKey: '⇧' }, specialKeyGlyphs: { BACKSPACE: '⌫', TAB: '⇥', ENTER: '⏎', RETURN: '⏎', SPACE: '␣', PAGE_UP: '⇞', PAGE_DOWN: '⇟', END: '⇲', HOME: '⌂', LEFT: '←', UP: '↑', RIGHT: '→', DOWN: '↓', PRINT_SCREEN: '⎙', INSERT: '⎀', DELETE: '⌦', CONTEXT_MENU: '☰' }, _hyphenRe: /^[a-z]+\-/i, getKeyId: function(keyName) { if (typeof keyName === 'number') { keyName = this.keyCodes[keyName]; } else { keyName = keyName.toUpperCase(); } var me = this, delim = me._hyphenRe.test(keyName) ? '-' : '+', parts = (keyName === delim) ? [ delim ] : keyName.split(delim), numModifiers = parts.length - 1, rawKey = parts[numModifiers], result = [], eventFlag, i; if (!Ext.event.Event[rawKey]) { Ext.raise('Invalid key name: "' + rawKey + '"'); } for (i = 0; i < numModifiers; i++) { eventFlag = me.keyFlags[parts[i]]; if (!eventFlag) { Ext.raise('Invalid key modifier: "' + parts[i] + '"'); } result[eventFlag] = true; } if (result.ctrlKey) { result.push(me.modifierGlyphs.ctrlKey); } if (result.altKey) { result.push(me.modifierGlyphs.altKey); } if (result.shiftKey) { result.push(me.modifierGlyphs.shiftKey); } if (result.metaKey) { result.push(me.modifierGlyphs.metaKey); } result.push(this.specialKeyGlyphs[rawKey] || rawKey); return result.join(''); }, globalTabKeyDown: function(e) { if (e.keyCode === 9) { Ext.event.Event.forwardTab = !e.shiftKey; } }, globalTabKeyUp: function(e) { if (e.keyCode === 9) { delete Ext.event.Event.forwardTab; } } }, 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.timeStamp = me.time = Ext.now(); me.pageX = coordinateOwner.pageX; me.pageY = coordinateOwner.pageY; me.clientX = coordinateOwner.clientX; me.clientY = coordinateOwner.clientY; me.target = me.delegatedTarget = resolveTextNode(event.target); me.currentTarget = resolveTextNode(event.currentTarget); relatedTarget = event.relatedTarget; if (relatedTarget) { if (Ext.isGecko && me.geckoRelatedTargetEvents[type]) { try { me.relatedTarget = resolveTextNode(relatedTarget); } catch (e) { me.relatedTarget = null; } } else { 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.focusEvents[type] || self.blurEvents[type]) { if (self.forwardTab !== undefined) { me.forwardTab = self.forwardTab; } if (self.focusEvents[type]) { me.fromElement = event.relatedTarget; me.toElement = event.target; } else { me.fromElement = event.target; me.toElement = event.relatedTarget; } } else if (type !== 'keydown') { delete self.forwardTab; } if (self.mouseEvents[type]) { pointerType = 'mouse'; } else if (self.clickEvents[type]) { pointerType = self.pointerTypeMap[event.pointerType] || (((Ext.now() - Ext.event.publisher.Dom.lastTouchEndTime) < 1000) ? 'touch' : 'mouse'); } else if (self.pointerEvents[type]) { pointerType = self.pointerTypeMap[event.pointerType] || 'mouse'; } else if (self.touchEvents[type]) { pointerType = 'touch'; } if (pointerType) { me.pointerType = pointerType; } me.isMultitouch = event.isPrimary === false || (event.touches && event.touches.length > 1); }, 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; }, getChar: function() { var r = this.which(); return String.fromCharCode(r); }, getCharCode: function() { return this.charCode || this.keyCode; }, getKey: function() { return this.keyCode || this.charCode; }, getKeyName: function() { return this.type === 'keypress' ? String.fromCharCode(this.getCharCode()) : this.keyCodes[this.keyCode]; }, key: function() { return this.browserEvent.key; }, which: function() { var me = this, e = me.browserEvent, r = e.which; if (r == null) { if (me.self.keyEventRe.test(e.type)) { r = e.charCode || e.keyCode; } else if ((r = e.button) !== undefined) { r = (r & 1) ? 1 : ((r & 4) ? 2 : ((r & 2) ? 3 : 0)); } } return r; }, getClipboardData: function(type) { var clipboardData = this.browserEvent.clipboardData, clipIE = Ext.global.clipboardData, result = null, typeIE; type = type || 'text/plain'; if (clipboardData && clipboardData.getData) { result = clipboardData.getData(type); } else if (clipIE && clipIE.getData) { typeIE = this.ieMimeType[type]; if (typeIE) { result = clipIE.getData(typeIE); } } return result; }, getPoint: function() { var me = this, point = me.point, xy; if (!point) { xy = me.getXY(); point = me.point = new Ext.util.Point(xy[0], xy[1]); } return point; }, getRelatedTarget: function(selector, maxDepth, returnEl) { var relatedTarget = this.relatedTarget, target = null; if (relatedTarget && relatedTarget.nodeType) { 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 ('deltaX' in event) { dx = event.deltaX; dy = -event.deltaY; } 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, isKeyPress = me.type === 'keypress'; return ((!isKeyPress || Ext.isGecko) && k >= 33 && k <= 40) || ( !scrollableOnly && (k === me.RETURN || k === me.TAB || k === me.ESC)); }, isSpecialKey: function() { var me = this, k = me.keyCode, isGecko = Ext.isGecko, isKeyPress = me.type === 'keypress'; return (isGecko && isKeyPress && me.charCode === 0) || (this.isNavKeyPress()) || (k === me.BACKSPACE) || (k === me.ENTER) || (k >= 16 && k <= 20) || ( (!isKeyPress || isGecko) && 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(); }, mousedownEvents: { mousedown: 1, pointerdown: 1, touchstart: 1 }, mouseupEvents: { mouseup: 1, pointerup: 1, touchend: 1 }, stopPropagation: function() { var me = this, browserEvent = me.browserEvent, parentEvent = me.parentEvent; if (me.mousedownEvents[me.type]) { Ext.GlobalEvents.fireMouseDown(me); } if (me.mouseupEvents[me.type]) { Ext.GlobalEvents.fireMouseUp(me); } me.stopped = true; if (parentEvent && !me.isGesture) { parentEvent.stopped = true; } if (!browserEvent.stopPropagation) { browserEvent.cancelBubble = true; return me; } browserEvent.stopPropagation(); return me; }, claimGesture: function() { var me = this, parentEvent = me.parentEvent; me.claimed = true; if (parentEvent && !me.isGesture) { parentEvent.claimGesture(); } else { me.preventDefault(); } return me; }, within: function(el, related, allowEl) { var t; if (el) { t = related ? this.getRelatedTarget() : this.getTarget(); } if (!t || (allowEl === false && t === Ext.getDom(el))) { return false; } return Ext.fly(el).contains(t); }, privates: { ieMimeType: { "text/plain": 'Text' } }, deprecated: { '4.0': { methods: { getPageX: 'getX', getPageY: 'getY' } } } }, function(Event) { var 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, META: 91, 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: 120 }, keyCodes = {}, gestureEvents = Event.gestureEvents, prototype = Event.prototype, i, keyName, keyCode, keys, s, scale; if (Ext.isGecko) { constants.WHEEL_SCALE = 3; } else if (Ext.isMac) { if (Ext.isSafari && Ext.webKitVersion >= 532) { scale = 120; } else { scale = 12; } constants.WHEEL_SCALE = 3 * scale; } Ext.apply(gestureEvents, Event.mouseEvents); Ext.apply(gestureEvents, Event.pointerEvents); Ext.apply(gestureEvents, Event.touchEvents); Ext.apply(Event, constants); Ext.apply(prototype, constants); delete constants.WHEEL_SCALE; delete constants.RETURN; for (keyName in constants) { keyCode = constants[keyName]; keyCodes[keyCode] = keyName; } Event.keyCodes = prototype.keyCodes = keyCodes; if (!Ext.isIE9m) { document.addEventListener('keydown', Event.globalTabKeyDown, true); document.addEventListener('keyup', Event.globalTabKeyUp, true); } prototype.getTrueXY = prototype.getXY; if (typeof KeyboardEvent !== 'undefined' && !('key' in KeyboardEvent.prototype)) { prototype._keys = keys = { 3: 'Cancel', 6: 'Help', 8: 'Backspace', 9: 'Tab', 12: 'Clear', 13: 'Enter', 16: 'Shift', 17: 'Control', 18: 'Alt', 19: 'Pause', 20: 'CapsLock', 27: 'Escape', 28: 'Convert', 29: 'NonConvert', 30: 'Accept', 31: 'ModeChange', 32: ' ', 33: 'PageUp', 34: 'PageDown', 35: 'End', 36: 'Home', 37: 'ArrowLeft', 38: 'ArrowUp', 39: 'ArrowRight', 40: 'ArrowDown', 41: 'Select', 42: 'Print', 43: 'Execute', 44: 'PrintScreen', 45: 'Insert', 46: 'Delete', 48: [ '0', ')' ], 49: [ '1', '!' ], 50: [ '2', '@' ], 51: [ '3', '#' ], 52: [ '4', '$' ], 53: [ '5', '%' ], 54: [ '6', '^' ], 55: [ '7', '&' ], 56: [ '8', '*' ], 57: [ '9', '(' ], 91: 'OS', 93: 'ContextMenu', 144: 'NumLock', 145: 'ScrollLock', 181: 'VolumeMute', 182: 'VolumeDown', 183: 'VolumeUp', 186: [ ';', ':' ], 187: [ '=', '+' ], 188: [ ',', '<' ], 189: [ '-', '_' ], 190: [ '.', '>' ], 191: [ '/', '?' ], 192: [ '`', '~' ], 219: [ '[', '{' ], 220: [ '\\', '|' ], 221: [ ']', '}' ], 222: [ "'", '"' ], 224: 'Meta', 225: 'AltGraph', 246: 'Attn', 247: 'CrSel', 248: 'ExSel', 249: 'EraseEof', 250: 'Play', 251: 'ZoomOut' }; for (i = 1; i < 25; ++i) { keys[i + 111] = 'F' + i; } for (i = 0; i < 26; ++i) { keys[i] = [ String.fromCharCode(i + 97), String.fromCharCode(i + 65) ]; } prototype.key = function() { var k = keys[this.browserEvent.which || this.keyCode]; if (k && typeof k !== 'string') { k = k[+this.shiftKey]; } return k; }; } }); Ext.define('Ext.event.publisher.Dom', { extend: Ext.event.publisher.Publisher, type: 'dom', handledDomEvents: [], reEnterCount: 0, captureEvents: { animationstart: 1, animationend: 1, resize: 1, focus: 1, blur: 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, scroll: 1, online: 1, offline: 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, supportsPassive = Ext.supports.PassiveEventListener; me.listenerOptions = supportsPassive ? { passive: false } : false; me.captureOptions = supportsPassive ? { passive: false, capture: true } : true; me.bubbleSubscribers = {}; me.captureSubscribers = {}; me.directSubscribers = {}; me.directCaptureSubscribers = {}; me.delegatedListeners = {}; me.initHandlers(); Ext.onInternalReady(me.onReady, me); me.callParent(); me.registerDomEvents(); }, registerDomEvents: function() { var me = this, publishersByEvent = Ext.event.publisher.Publisher.publishersByEvent, domEvents = me.handledDomEvents, ln = domEvents.length, i, eventName; for (i = 0; i < ln; i++) { eventName = domEvents[i]; me.handles[eventName] = 1; publishersByEvent[eventName] = me; } }, 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, { priority: -10000 }); }, 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) { var me = this; me.delegatedListeners[eventName] = 1; me.target.addEventListener(eventName, me.onDelegatedEvent, me.captureEvents[eventName] ? me.captureOptions : me.listenerOptions); }, removeDelegatedListener: function(eventName) { var me = this; delete me.delegatedListeners[eventName]; me.target.removeEventListener(eventName, me.onDelegatedEvent, me.captureEvents[eventName] ? me.captureOptions : me.listenerOptions); }, addDirectListener: function(eventName, element, capture) { var me = this; element.dom.addEventListener(eventName, capture ? me.onDirectCaptureEvent : me.onDirectEvent, capture ? me.captureOptions : me.listenerOptions); }, removeDirectListener: function(eventName, element, capture) { var me = this; element.dom.removeEventListener(eventName, capture ? me.onDirectCaptureEvent : me.onDirectEvent, capture ? me.captureOptions : me.listenerOptions); }, 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(e, targets, claimed) { var me = this, hasCaptureSubscribers = false, hasBubbleSubscribers = false, events, type, target, el, i, ln, j, eLn; claimed = claimed || false; if (!targets) { if (e instanceof Array) { Ext.raise("Propagation targets must be supplied when publishing an array of events."); } target = e.target; if (me.captureEvents[e.type]) { el = Ext.cache[target.id]; targets = el ? [ el ] : []; } else { targets = me.getPropagatingTargets(target); } } events = Ext.Array.from(e); ln = targets.length; eLn = events.length; for (i = 0; i < eLn; i++) { type = events[i].type; if (!hasCaptureSubscribers && me.captureSubscribers[type]) { hasCaptureSubscribers = true; } if (!hasBubbleSubscribers && me.bubbleSubscribers[type]) { hasBubbleSubscribers = true; } } if (hasCaptureSubscribers) { for (i = ln; i--; ) { el = Ext.cache[targets[i].id]; if (el) { for (j = 0; j < eLn; j++) { e = events[j]; me.fire(el, e.type, e, false, true); if (!claimed && e.claimed) { claimed = true; j = me.filterClaimed(events, e); eLn = events.length; } if (e.stopped) { events.splice(j, 1); j--; eLn--; } } } } } if (hasBubbleSubscribers && !e.stopped) { for (i = 0; i < ln; i++) { el = Ext.cache[targets[i].id]; if (el) { for (j = 0; j < eLn; j++) { e = events[j]; me.fire(el, e.type, e, false, false); if (!claimed && e.claimed && me.filterClaimed) { claimed = true; j = me.filterClaimed(events, e); eLn = events.length; } if (e.stopped) { events.splice(j, 1); j--; eLn--; } } } } } }, publishDelegatedDomEvent: function(e) { this.publish(e); }, 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) { var me = this, timeStamp; e = new Ext.event.Event(e); timeStamp = e.time; if (!me.isEventBlocked(e)) { me.beforeEvent(e); Ext.frameStartTime = timeStamp; me.reEnterCountAdjusted = false; me.reEnterCount++; me.publishDelegatedDomEvent(e); if (!me.reEnterCountAdjusted) { me.reEnterCount--; } me.afterEvent(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, el; e = new Ext.event.Event(e); timeStamp = e.time; if (me.isEventBlocked(e)) { return; } me.beforeEvent(e); Ext.frameStartTime = timeStamp; el = Ext.cache[currentTarget.id]; if (el) { me.reEnterCountAdjusted = false; me.reEnterCount++; me.fire(el, e.type, e, true, capture); if (!me.reEnterCountAdjusted) { 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.idleEventMask[type]) { Ext.fireIdle(); } }, isEventBlocked: function(e) { var me = this, type = e.type, self = Ext.event.publisher.Dom, now = Ext.now(); if (Ext.isGecko && e.type === 'click' && e.button === 2) { return true; } 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 GC = Ext.dom['GarbageCollector'], eventName; for (eventName in this.delegatedListeners) { this.removeDelegatedListener(eventName); } Ext.Reaper.flush(); if (GC) { GC.collect(); } this.callParent(); }, reset: function() { var self = Ext.event.publisher.Dom; this.reEnterCount = 0; 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.event.publisher.Gesture', { extend: Ext.event.publisher.Dom, type: 'gesture', isCancelEvent: { touchcancel: 1, pointercancel: 1, MSPointerCancel: 1 }, isEndEvent: { mouseup: 1, touchend: 1, pointerup: 1, MSPointerUp: 1 }, handledEvents: [], handledDomEvents: [], constructor: function(config) { var me = this, handledDomEvents = me.handledDomEvents, supports = Ext.supports, supportsTouchEvents = supports.TouchEvents, onTouchStart = me.onTouchStart, onTouchMove = me.onTouchMove, onTouchEnd = me.onTouchEnd; 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.activeTouchesMap = {}; me.activeTouches = []; me.changedTouches = []; me.recognizers = []; me.eventToRecognizer = {}; me.cancelEvents = []; 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.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, eventName, i; recognizer.setOnRecognized(me.onRecognized); recognizer.setCallbackScope(me); for (i = 0; i < ln; i++) { eventName = handledEvents[i]; me.handledEvents.push(eventName); me.eventToRecognizer[eventName] = recognizer; } me.registerEvents(handledEvents); me.recognizers.push(recognizer); }, onRecognized: function(recognizer, eventName, e, info, isCancel) { var me = this, touches = e.touches, changedTouches = e.changedTouches, ln = changedTouches.length, events = me.events, queueWasEmpty = !events.length, cancelEvents = me.cancelEvents, targetGroups, targets, i, touch; info = info || {}; info.type = eventName; info.target = changedTouches[0].target; info.stopped = false; info.claimed = false; info.isGesture = true; e = e.chain(info); if (!me.gestureTargets) { 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.gestureTargets = targets; } if (isCancel && recognizer.isSingleTouch && (touches.length > 1)) { e.target = touches[0].target; cancelEvents.push(e); } else { events.push(e); } if (queueWasEmpty) { me.publishGestures(); } }, 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; } } }, filterClaimed: function(events, claimedEvent) { var me = this, eventToRecognizer = me.eventToRecognizer, claimedEventType = claimedEvent.type, claimedRecognizer = eventToRecognizer[claimedEventType], claimedEventIndex, recognizer, type, i; for (i = events.length; i--; ) { type = events[i].type; if (type === claimedEventType) { claimedEventIndex = i; } else { recognizer = eventToRecognizer[type]; if (!claimedRecognizer || (recognizer && (recognizer !== claimedRecognizer))) { events.splice(i, 1); if (claimedEventIndex) { claimedEventIndex--; } } } } me.claimRecognizer(claimedRecognizer, events[0]); return claimedEventIndex; }, claimRecognizer: function(claimedRecognizer, e) { var me = this, recognizers = me.recognizers, i, ln, recognizer; for (i = 0 , ln = recognizers.length; i < ln; i++) { recognizer = recognizers[i]; if (recognizer !== claimedRecognizer) { recognizer.isActive = false; recognizer.cancel(e); } } if (me.events.length) { me.publishGestures(true); } }, publishGestures: function(claimed) { var me = this, cancelEvents = me.cancelEvents, events = me.events, gestureTargets = me.gestureTargets; if (cancelEvents.length) { me.cancelEvents = []; me.publish(cancelEvents, me.getPropagatingTargets(cancelEvents[0].target), true); } if (events.length) { me.events = []; me.gestureTargets = null; me.publish(events, gestureTargets || me.getPropagatingTargets(events[0].target), claimed); } }, updateTouches: function(e) { var me = this, browserEvent = e.browserEvent, type = e.type, 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 (me.isEndEvent[type] || me.isCancelEvent[type]) { 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; }, publishDelegatedDomEvent: function(e) { var me = this; if (!e.button || e.button < 1) { me.events = [ e ]; e.browserEvent.$extHandled = true; me.handlers[e.type].call(me, e); } else { me.callParent([ e ]); } }, onTouchStart: function(e) { var me = this, target = e.target, touches = e.browserEvent.touches; if (e.browserEvent.type === 'touchstart') { target.addEventListener('touchmove', me.onTargetTouchMove); target.addEventListener('touchend', me.onTargetTouchEnd); target.addEventListener('touchcancel', me.onTargetTouchEnd); } if (touches && touches.length <= me.activeTouches.length) { me.removeGhostTouches(touches); } me.updateTouches(e); if (!me.isStarted) { if (Ext.enableGarbageCollector) { Ext.dom.GarbageCollector.pause(); } me.isStarted = true; me.invokeRecognizers('onStart', e); } me.invokeRecognizers('onTouchStart', e); me.publishGestures(); }, onTouchMove: function(e) { var me = this, mousePointerType = me.mousePointerType, isStarted = me.isStarted; if (isStarted || (e.pointerType !== 'mouse')) { me.updateTouches(e); } if (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; } if (e.changedTouches.length > 0) { me.invokeRecognizers('onTouchMove', e); } } me.publishGestures(); }, onTouchEnd: function(e) { var me = this, isStarted = me.isStarted, touchCount; if (isStarted || (e.pointerType !== 'mouse')) { me.updateTouches(e); } if (!isStarted) { me.publishGestures(); return; } touchCount = me.activeTouches.length; try { me.invokeRecognizers(me.isCancelEvent[e.type] ? 'onTouchCancel' : 'onTouchEnd', e); } finally { try { if (!touchCount) { me.isStarted = false; me.invokeRecognizers('onEnd', e); } } finally { try { me.publishGestures(); } finally { if (!touchCount) { if (Ext.enableGarbageCollector) { Ext.dom.GarbageCollector.resume(); } } me.reEnterCountAdjusted = true; me.reEnterCount--; } } } }, onTargetTouchMove: function(e) { if (Ext.elevateFunction) { Ext.elevateFunction(this.doTargetTouchMove, this, [ e ]); } else { this.doTargetTouchMove(e); } }, doTargetTouchMove: function(e) { var me = this; if (!Ext.getBody().contains(e.target)) { me.reEnterCountAdjusted = false; me.reEnterCount++; this.onTouchMove(new Ext.event.Event(e)); if (!me.reEnterCountAdjusted) { me.reEnterCount--; } } }, 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.reEnterCountAdjusted = false; me.reEnterCount++; me.onTouchEnd(new Ext.event.Event(e)); if (!me.reEnterCountAdjusted) { me.reEnterCount--; } } }, reset: function() { var me = this, recognizers = me.recognizers, ln = recognizers.length, i, recognizer; me.activeTouchesMap = {}; me.activeTouches = []; me.changedTouches = []; me.isStarted = false; me.gestureTargets = null; me.events = []; me.cancelEvents = []; for (i = 0; i < ln; i++) { recognizer = recognizers[i]; recognizer.reset(); recognizer.isActive = false; } this.callParent(); }, privates: { removeGhostTouches: function(touches) { var ids = {}, len = touches.length, activeTouches = this.activeTouches, map = this.activeTouchesMap, i, id, touch; for (i = 0; i < len; ++i) { ids[touches[i].identifier] = true; } i = activeTouches.length; while (i--) { touch = activeTouches[i]; id = touch.identifier; if (!touches[id]) { Ext.Array.remove(activeTouches, touch); delete map[id]; } } } } }, function(Gesture) { var EventProto = Event.prototype, stopPropagation = EventProto.stopPropagation; if (stopPropagation) { EventProto.stopPropagation = function() { var me = this, publisher = Gesture.instance, type = me.type, e; if (!me.$extHandled && publisher.handles[type]) { e = new Ext.event.Event(me); publisher.updateTouches(e); publisher.invokeRecognizers('onTouchCancel', e); publisher.reset(); publisher.reEnterCountAdjusted = true; } stopPropagation.apply(me, arguments); }; } Gesture.instance = Ext.$gesturePublisher = new Gesture(); }); 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', { singleton: true, pending: false, mode: true, protectedReadQueue: [], protectedWriteQueue: [], readQueue: [], writeQueue: [], readRequestId: 0, writeRequestId: 0, timer: null, constructor: function() { var me = this; me.run = me.run.bind(me); me.runProtected = Ext.Function.bind(me.run, me, [ me.protectedReadQueue, me.protectedWriteQueue, 'runProtected' ]); me.runProtected.$skipTimerCheck = true; if (Ext.os.is.iOS) { me.watch.$skipTimerCheck = true; me.watchdogTimer = Ext.interval(this.watch, 500, this); } }, requestRead: function(fn, scope, args) { var request = { id: ++this.readRequestId, fn: fn, scope: scope, args: args }; if (arguments[3] === true) { this.protectedReadQueue.push(request); this.request(true, 'runProtected'); } else { this.readQueue.push(request); this.request(true); } return request.id; }, cancelRead: function(id) { this.cancelRequest(this.readQueue, id, true); }, requestWrite: function(fn, scope, args) { var me = this, request = { id: ++me.writeRequestId, fn: fn, scope: scope, args: args }; if (arguments[3] === true) { me.protectedWriteQueue.push(request); me.request(false, 'runProtected'); } else { me.writeQueue.push(request); me.request(false); } return request.id; }, cancelWrite: function(id) { this.cancelRequest(this.writeQueue, id, false); }, request: function(mode, method) { var me = this; var oldMode = me.mode; if (!me.pending) { me.pendingTime = Date.now(); me.pending = true; me.mode = mode; if (mode) { me.timer = Ext.defer(me[method] || me.run, 1); } else { me.timer = Ext.raf(me[method] || me.run); } } if (me.mode === mode && me.timer) { if (oldMode) { Ext.undefer(me.timer); } else { Ext.unraf(me.timer); } if (mode) { me.timer = Ext.defer(me[method] || me.run, 1); } else { me.timer = Ext.raf(me[method] || me.run); } } }, cancelRequest: function(queue, id, mode) { for (var i = 0; i < queue.length; i++) { if (queue[i].id === id) { queue.splice(i, 1); break; } } if (!queue.length && this.mode === mode && this.timer) { Ext.undefer(this.timer); } }, watch: function() { if (this.pending && Date.now() - this.pendingTime >= 500) { this.run(); } }, run: function(readQueue, writeQueue, method) { var me = this, mode = null, queue, tasks, task, fn, scope, args, i, len; readQueue = readQueue || me.readQueue; writeQueue = writeQueue || me.writeQueue; me.pending = false; me.pending = me.timer = false; if (me.mode) { queue = readQueue; if (writeQueue.length > 0) { mode = false; } } else { queue = writeQueue; if (readQueue.length > 0) { mode = true; } } tasks = queue.slice(); queue.length = 0; for (i = 0 , len = tasks.length; i < len; i++) { task = tasks[i]; fn = task.fn; scope = task.scope; args = task.args; if (scope && (scope.destroying || scope.destroyed)) { continue; } if (typeof fn === 'string') { fn = scope[fn]; } if (args) { fn.apply(scope, args); } else { fn.call(scope); } } tasks.length = 0; if (mode !== null) { me.request(mode, method); } }, clear: function() { var me = this, timer = me.timer; if (timer) { if (me.mode) { Ext.undefer(timer); } else { Ext.unraf(timer); } } me.readQueue.length = me.writeQueue.length = 0; me.pending = me.timer = false; me.mode = true; }, privates: { flush: function() { var me = this, mode = me.mode; while (me.readQueue.length || me.writeQueue.length) { if (mode) { Ext.undefer(me.timer); } else { Ext.unraf(me.timer); } me.run(); } me.mode = true; } } }); Ext.define('Ext.util.sizemonitor.Abstract', { mixins: [ Ext.mixin.Templatable ], config: { element: null, callback: Ext.emptyFn, scope: null, args: [] }, width: null, height: null, contentWidth: null, contentHeight: null, constructor: function(config) { var me = this; me.refresh = me.refresh.bind(me); me.info = { width: 0, height: 0, contentWidth: 0, contentHeight: 0, flag: 0 }; me.initElement(); me.initConfig(config); me.bindListeners(true); }, bindListeners: Ext.emptyFn, applyElement: function(element) { if (element) { return Ext.get(element); } }, updateElement: function(element) { element.append(this.detectorsContainer, true); 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.clientWidth; }, getContentHeight: function() { return this.detectorsContainer.clientHeight; }, refreshSize: function() { var element = this.getElement(); if (!element || element.destroyed) { return false; } var me = this, size = element.measure(), width = size.width, height = size.height, contentWidth = me.getContentWidth(), contentHeight = me.getContentHeight(), currentContentWidth = me.contentWidth, currentContentHeight = me.contentHeight, info = me.info, resized = false, flag; me.width = width; me.height = height; me.contentWidth = contentWidth; me.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; me.getCallback().apply(me.getScope(), me.getArgs()); } return resized; }, refresh: function() { if (this.destroying || this.destroyed) { return; } this.refreshSize(); Ext.TaskQueue.requestWrite('refreshMonitors', this); }, destroy: function() { var me = this, element = me.getElement(); me.bindListeners(false); if (element && !element.destroyed) { element.removeCls(Ext.baseCSSPrefix + 'size-monitored'); } delete me._element; me.refresh = null; me.callParent(); } }); 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 = this.onScroll.bind(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); }, onScroll: function() { if (!this.destroyed) { Ext.TaskQueue.requestRead('refresh', this); } }, refreshMonitors: function() { var expandMonitor = this.expandMonitor, shrinkMonitor = this.shrinkMonitor, end = 1000000; if (expandMonitor && !expandMonitor.destroyed) { expandMonitor.scrollLeft = end; expandMonitor.scrollTop = end; } if (shrinkMonitor && !shrinkMonitor.destroyed) { shrinkMonitor.scrollLeft = end; shrinkMonitor.scrollTop = end; } }, destroy: function() { this.onScroll = null; this.callParent(); } }); Ext.define('Ext.util.SizeMonitor', { constructor: function(config) { return new Ext.util.sizemonitor.Scroll(config); } }); Ext.define('Ext.event.publisher.ElementSize', { extend: Ext.event.publisher.Publisher, 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]; } if (element.activeRead) { Ext.TaskQueue.cancelRead(element.activeRead); } }, fireElementResize: function(element, info) { delete element.activeRead; this.fire(element, 'resize', [ element, info ]); }, onElementResize: function(element, info) { if (!element.activeRead) { element.activeRead = Ext.TaskQueue.requestRead('fireElementResize', this, [ element, info ], !!element.$skipResourceCheck); } }, privates: { syncRefresh: function(elements) { elements = Ext.Array.from(elements); var len = elements.length, i = 0, el, monitor; for (i = 0; i < len; ++i) { el = elements[i]; if (typeof el !== 'string') { el = el.id; } monitor = this.monitors[el]; if (monitor) { monitor.forceRefresh(); } } Ext.TaskQueue.flush(); Ext.Function.fireElevatedHandlers(); } } }, 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 = this.onElementPainted.bind(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, true); element.addCls(Ext.baseCSSPrefix + 'paint-monitored'); this.bindListeners(true); }, onElementPainted: function() {}, destroy: function() { var me = this, monitorElement = me.monitorElement, parentNode = monitorElement.parentNode, element = me.getElement(); me.bindListeners(false); delete me.monitorElement; if (element && !element.destroyed) { element.removeCls(Ext.baseCSSPrefix + 'paint-monitored'); delete me._element; } if (parentNode) { parentNode.removeChild(monitorElement); } me.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', { constructor: function(config) { return new Ext.util.paintmonitor.CssAnimation(config); } }); Ext.define('Ext.event.publisher.ElementPaint', { extend: Ext.event.publisher.Publisher, type: 'paint', handledEvents: [ 'painted' ], constructor: function() { this.monitors = {}; this.subscribers = {}; this.callParent(arguments); }, subscribe: function(element) { var me = this, id = element.id, subscribers = me.subscribers; if (subscribers[id]) { ++subscribers[id]; } else { subscribers[id] = 1; me.monitors[id] = new Ext.util.PaintMonitor({ element: element, callback: me.onElementPainted, scope: me, 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]; } if (element.activeRead) { Ext.TaskQueue.cancelRead(element.activeRead); } }, fireElementPainted: function(element) { delete element.activeRead; this.fire(element, 'painted', [ element ]); }, onElementPainted: function(element) { if (!element.activeRead) { element.activeRead = Ext.TaskQueue.requestRead('fireElementPainted', this, [ element ], !!element.$skipResourceCheck); } } }, function(ElementPaint) { ElementPaint.instance = new ElementPaint(); }); Ext.define('Ext.dom.Element', function(Element) { var WIN = window, DOC = document, docEl = DOC.documentElement, WIN_TOP = WIN.top, EMPTY = [], elementIdCounter, windowId, documentId, 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", wordsRe = /\w/g, spacesRe = /\s+/, classNameSplitRegex = /[\s]+/, transparentRe = /^(?:transparent|(?:rgba[(](?:\s*\d+\s*[,]){3}\s*0\s*[)]))$/i, endsQuestionRe = /\?$/, topRe = /top/i, empty = {}, 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' }, selectDir = { b: 'backward', back: 'backward', f: 'forward' }, paddingsTLRB = [ paddings.l, paddings.r, paddings.t, paddings.b ], bordersTLRB = [ borders.l, borders.r, borders.t, borders.b ], numberRe = /\d+$/, unitRe = /\d+(px|r?em|%|vh|vw|vmin|vmax|en|ch|ex|pt|in|cm|mm|pc)$/i, defaultUnit = 'px', msRe = /^-ms-/, camelRe = /(-[a-z])/gi, cssRe = /([a-z0-9\-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi, pxRe = /^\d+(?:\.\d*)?px$/i, relativeUnitRe = /(%|r?em|auto|vh|vw|vmin|vmax|ch|ex)$/i, propertyCache = {}, ORIGINALDISPLAY = 'originalDisplay', camelReplaceFn = function(m, a) { return a.charAt(1).toUpperCase(); }, clearData = function(node, deep) { var childNodes, i, len; if (node.nodeType === 1) { node._extData = null; if (deep) { childNodes = node.childNodes; for (i = 0 , len = childNodes.length; i < len; ++i) { clearData(childNodes[i], deep); } } } }, toFloat = function(v) { return parseFloat(v) || 0; }, opacityCls = Ext.baseCSSPrefix + 'hidden-opacity', visibilityCls = Ext.baseCSSPrefix + 'hidden-visibility', displayCls = Ext.baseCSSPrefix + 'hidden-display', offsetsCls = Ext.baseCSSPrefix + 'hidden-offsets', clipCls = Ext.baseCSSPrefix + 'hidden-clip', lastFocusChange = 0, lastKeyboardClose = 0, editableHasFocus = false, isVirtualKeyboardOpen = false, inputTypeSelectionSupported = /text|password|search|tel|url/i, visFly, scrollFly, caFly, wrapFly, grannyFly, activeElFly; try { elementIdCounter = WIN_TOP.__elementIdCounter__; WIN_TOP.__elementIdCounter__ = elementIdCounter; } catch (e) { WIN_TOP = WIN; } WIN_TOP.__elementIdCounter__ = elementIdCounter = (WIN_TOP.__elementIdCounter__ || 0) + 1; windowId = 'ext-window-' + elementIdCounter; documentId = 'ext-document-' + elementIdCounter; if (Object.freeze) { Object.freeze(EMPTY); } return { alternateClassName: [ 'Ext.Element' ], mixins: [ Ext.util.Positionable, Ext.mixin.Observable ], observableType: 'element', isElement: true, skipGarbageCollection: true, $applyConfigs: true, identifiablePrefix: 'ext-element-', _selectDir: selectDir, styleHooks: { transform: { set: function(dom, value, el) { var prop, result = ''; if (typeof value !== 'string') { for (prop in value) { if (result) { result += ' '; } if (prop.indexOf('translate') === 0) { result += prop + '(' + Element.addUnits(value[prop], 'px') + ')'; } else { result += prop + '(' + value[prop] + ')'; } } value = result; } dom.style.transform = value; } } }, 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.raise("Invalid domNode reference or an id of an existing domNode: " + dom); return null; } if (Ext.cache[dom.id]) { Ext.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.raise('Invalid Element "id": "' + me.id + '"'); } me.el = me; Ext.cache[id] = me; me.longpressListenerCount = 0; me.mixins.observable.constructor.call(me); }, inheritableStatics: { cache: Ext.cache = {}, editableSelector: 'input,textarea,[contenteditable="true"]', VISIBILITY: 1, DISPLAY: 2, OFFSETS: 3, CLIP: 4, OPACITY: 5, minKeyboardHeight: 100, unitRe: unitRe, useDelegatedEvents: true, validNodeTypes: { 1: 1, 9: 1 }, namespaceURIs: { html: 'http://www.w3.org/1999/xhtml', svg: 'http://www.w3.org/2000/svg' }, selectableCls: Ext.baseCSSPrefix + 'selectable', unselectableCls: Ext.baseCSSPrefix + 'unselectable', maxRippleDiameter: 75, 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)) { if (!(Ext.isString(size) && size.indexOf('calc') === 0)) { 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, classes, element, elementStyle, tag, value, name, i, ln, tmp, ns; 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'; } ns = attributes.namespace; if (ns) { element = DOC.createElementNS(me.namespaceURIs[ns] || ns, tag); } else { element = DOC.createElement(tag); } elementStyle = element.style; for (name in attributes) { if (name !== 'tag') { value = attributes[name]; switch (name) { case 'style': if (typeof value === 'string') { element.setAttribute(name, value); } else { for (i in value) { elementStyle[i] = value[i]; } }; break; case 'className': case 'cls': tmp = value.split(spacesRe); classes = classes ? classes.concat(tmp) : tmp; break; case 'classList': classes = classes ? classes.concat(value) : value; break; case 'text': element.textContent = value; break; case 'html': element.innerHTML = value; break; case 'hidden': if (classes) { classes.push(displayCls); } else { classes = [ displayCls ]; }; break; case 'children': if (value != null) { 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 (classes) { element.className = classes.join(' '); } if (domNode) { return element; } else { return me.get(element); } }, fly: function(dom, named) { return Ext.fly(dom, named); }, fromPoint: (function() { var elementFromPointBug; if (Ext.isIE || Ext.isEdge) { try { elementFromPointBug = window.self !== window.top; } catch (e) { elementFromPointBug = true; } } return function(x, y, asDom) { var el = null; el = DOC.elementFromPoint(x, y); if (!el && elementFromPointBug) { el = DOC.elementFromPoint(x, y); } return asDom ? el : Ext.get(el); }; })(), fromPagePoint: function(x, y, asDom) { var scroll = Ext.getDoc().getScroll(); return Element.fromPoint(x - scroll.left, y - scroll.top, asDom); }, get: function(el) { var me = this, cache = Ext.cache, nodeType, dom, id, entry, isDoc, isWin, isValidNodeType; if (!el) { return null; } function warnDuplicate(id) { Ext.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(asElement) { var active = DOC.activeElement; if (!active || !active.focus) { active = DOC.body; } return asElement ? Ext.get(active) : active; }, getDocumentHeight: function() { return Math.max(!Ext.isStrict ? DOC.body.scrollHeight : docEl.scrollHeight, this.getViewportHeight()); }, getDocumentWidth: function() { return Math.max(!Ext.isStrict ? DOC.body.scrollWidth : docEl.scrollWidth, this.getViewportWidth()); }, getOrientation: function() { if (Ext.supports.OrientationChange) { return (WIN.orientation == 0) ? 'portrait' : 'landscape'; } return (WIN.innerHeight > WIN.innerWidth) ? 'portrait' : 'landscape'; }, getViewportHeight: function() { var viewportHeight = Element._viewportHeight; if (Ext.isIE9m) { return DOC.documentElement.clientHeight; } return (viewportHeight != null) ? viewportHeight : docEl.clientHeight; }, getViewportWidth: function() { var viewportWidth = Element._viewportWidth; if (Ext.isIE9m) { return DOC.documentElement.clientWidth; } return (viewportWidth != null) ? viewportWidth : docEl.clientWidth; }, getViewportScale: function() { var top = WIN_TOP; return ((Ext.isiOS || Ext.isAndroid) ? 1 : (top.devicePixelRatio || top.screen.deviceXDPI / top.screen.logicalXDPI)) * this.getViewportTouchScale(); }, getViewportTouchScale: function(forceRead) { var scale = 1, top = WIN_TOP, cachedScale; if (!forceRead) { cachedScale = this._viewportTouchScale; if (cachedScale) { return cachedScale; } } if (Ext.isIE10p || Ext.isEdge || Ext.isiOS) { scale = docEl.offsetWidth / WIN.innerWidth; } else if (Ext.isChromeMobile) { scale = top.outerWidth / top.innerWidth; } return scale; }, getViewSize: function() { return { width: Element.getViewportWidth(), height: Element.getViewportHeight() }; }, hasUnit: function(size) { return !!(size && unitRe.test(size)); }, isRelativeUnit: function(size) { return !size || relativeUnitRe.test(size); }, maskIframes: function() { var iframes = document.getElementsByTagName('iframe'), fly = new Ext.dom.Fly(); Ext.each(iframes, function(iframe) { var myMask; myMask = fly.attach(iframe.parentNode).mask(); myMask.setStyle('background-color', 'transparent'); }); }, normalize: function(prop) { return propertyCache[prop] || (propertyCache[prop] = prop.replace(msRe, 'ms-').replace(camelRe, camelReplaceFn)); }, _onWindowFocusChange: function(e) { if (Ext.fly(e.target).is(Element.editableSelector)) { lastFocusChange = new Date(); editableHasFocus = (e.type === 'focusin' || e.type === 'pointerup'); } }, _onWindowResize: function() { var documentWidth = docEl.clientWidth, documentHeight = docEl.clientHeight, now = new Date(), threshold = 1000, deltaX, deltaY; deltaX = documentWidth - Element._documentWidth; deltaY = documentHeight - Element._documentHeight; Element._documentWidth = documentWidth; Element._documentHeight = documentHeight; if (((now - lastFocusChange) < threshold) || ((now - lastKeyboardClose) < threshold)) { if (deltaX === 0 && (editableHasFocus && (deltaY <= -Element.minKeyboardHeight))) { isVirtualKeyboardOpen = true; return; } } if (isVirtualKeyboardOpen && (deltaX === 0) && (deltaY >= Element.minKeyboardHeight)) { isVirtualKeyboardOpen = false; lastKeyboardClose = new Date(); } if (isVirtualKeyboardOpen) { return; } Element._viewportWidth = documentWidth; Element._viewportHeight = documentHeight; }, 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); }, unmaskIframes: function() { var iframes = document.getElementsByTagName('iframe'), fly = new Ext.dom.Fly(); Ext.each(iframes, function(iframe) { fly.attach(iframe.parentNode).unmask(); }); }, 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(DOC.body); break; } } return returnDom ? caFly.dom : Ext.get(caFly); } }, selectable: function() { var me = this; me.dom.unselectable = ''; me.removeCls(Element.unselectableCls); me.addCls(Element.selectableCls); return me; }, unselectable: function() { var me = this; if (Ext.isOpera) { me.dom.unselectable = 'on'; } me.removeCls(Element.selectableCls); me.addCls(Element.unselectableCls); return me; }, statics: { tabbableSelector: Ext.supports.CSS3NegationSelector ? 'a[href],button,iframe,input,select,textarea,[tabindex]:not([tabindex="-1"]),[contenteditable="true"]' : '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, BODY: Ext.isIE ? false : true }, naturallyTabbableTags: { BUTTON: true, IFRAME: true, INPUT: true, SELECT: true, TEXTAREA: true, OBJECT: Ext.isIE8m ? true : false }, inputTags: { INPUT: true, TEXTAREA: true }, tabbableSavedCounterAttribute: 'data-tabindex-counter', tabbableSavedValueAttribute: 'data-tabindex-value', splitCls: function(cls) { if (typeof cls === 'string') { cls = cls.split(spacesRe); } return cls; } }, _init: function(E) { E.tabbableSelector += ',[' + E.tabbableSavedCounterAttribute + ']'; }, addCls: function(names, prefix, suffix) { return this.replaceCls(null, names, prefix, suffix); }, addClsOnClick: function(className, testFn, scope) { var me = this, hasTest = Ext.isFunction(testFn); me.on("mousedown", function() { if (hasTest && testFn.call(scope || me, me) === false) { return false; } me.addCls(className); Ext.getDoc().on({ mouseup: function() { if (me.dom) { me.removeCls(className); } }, single: true }); }); return me; }, addClsOnFocus: function(className, testFn, scope) { var me = this, hasTest = Ext.isFunction(testFn); me.on("focus", function() { if (hasTest && testFn.call(scope || me, me) === false) { return false; } me.addCls(className); }); me.on("blur", function() { if (me.dom) { me.removeCls(className); } }); return me; }, addClsOnOver: function(className, testFn, scope) { var me = this, hasTest = Ext.isFunction(testFn); me.hover(function() { if (hasTest && testFn.call(scope || me, me) === false) { return; } me.addCls(className); }, function() { me.removeCls(className); }); return me; }, addStyles: function(sides, styles) { var totalSize = 0, sidesArr = (sides || '').match(wordsRe), i, len = sidesArr.length, side, styleSides = []; if (len === 1) { totalSize = 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); }, animate: function(animation) { animation = new Ext.fx.Animation(animation); animation.setElement(this); this._activeAnimation = animation; animation.on({ animationend: this._onAnimationEnd, scope: this }); Ext.Animator.run(animation); return animation; }, _onAnimationEnd: function() { this._activeAnimation = null; }, getActiveAnimation: function() { return this._activeAnimation; }, append: function() { return 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(DOC.createDocumentFragment()); eLen = el.length; for (e = 0; e < eLen; e++) { insertEl.appendChild(el[e], returnDom); } el = Ext.Array.toArray(insertEl.dom.childNodes); me.dom.appendChild(insertEl.dom); return returnDom ? el : new Ext.dom.CompositeElementLite(el); } 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; if (Ext.supports.Selectors2) { return me.selectNode(':scope>' + selector, !!returnDom); } else { id = me.id != null ? me.id : Ext.get(me).id; return me.selectNode(Ext.makeIdSelector(id) + " > " + selector, !!returnDom); } }, clone: function(deep, returnDom) { var clone = this.dom.cloneNode(deep); if (Ext.supports.CloneNodeCopiesExpando) { clearData(clone, deep); } return returnDom ? clone : Ext.get(clone); }, 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.destroyed) { Ext.Logger.warn("Cannot destroy Element \"" + me.id + "\". Already destroyed."); return; } if (me.resumeFocusEventsTimer) { Ext.unasap(me.resumeFocusEventsTimer); me.resumeFocusEventsTimer = null; } if (me.repaintTimer) { me.repaintTimer = Ext.undefer(me.repaintTimer); } if (me.deferFocusTimer) { me.deferFocusTimer = Ext.undefer(me.deferFocusTimer); } if (dom) { if (dom === DOC.body) { Ext.raise("Cannot destroy body element."); } else if (dom === DOC) { Ext.raise("Cannot destroy document object."); } else if (dom === WIN) { Ext.raise("Cannot destroy window object"); } } if (dom && dom.parentNode) { dom.parentNode.removeChild(dom); } if (me.$ripples) { me.destroyAllRipples(); } me.collect(); }, detach: function() { var dom = this.dom, component = this.component; if (dom && dom.parentNode && dom.tagName !== 'BODY') { if (component) { component.revertFocus(); } 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; } }, 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; return shim; }, findParent: function(simpleSelector, limit, returnEl) { var me = this, target = me.dom, topmost = docEl, 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; if (Number(defer)) { Ext.defer(me.focus, defer, me, [ null, dom ]); } else { Ext.GlobalEvents.fireEvent('beforefocus', dom); dom.focus(); } 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.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); }, getClassMap: function(clone) { var data = this.getData(); if (data) { data = data.classMap; if (clone !== false) { data = Ext.apply({}, data); } } return data; }, getData: function(sync) { var dom = this.dom, data; if (dom) { data = dom._extData || (dom._extData = {}); if (sync !== false && !data.isSynchronized) { this.synchronize(); } } return data || null; }, getFirstChild: function() { return Ext.get(this.dom.firstElementChild); }, getLastChild: function() { return Ext.get(this.dom.lastElementChild); }, getHeight: function(contentHeight, preciseHeight) { var me = this, dom = me.dom, hidden = me.isStyle('display', 'none'), height, floating; if (hidden) { return 0; } if (dom.nodeName === 'BODY') { height = Element.getViewportHeight(); } else { if (preciseHeight) { height = dom.getBoundingClientRect().height; } else { height = dom.offsetHeight; if (height == null) { height = dom.getBoundingClientRect().height; } } } 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 = docEl, left, top, body = DOC.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, align) { align = align || empty; var me = this, dom = me.dom, offsets, clientWidth, clientHeight; if (container.isRegion) { clientHeight = container.height; clientWidth = container.width; } else { container = Ext.getDom(container); clientHeight = container.clientHeight; clientWidth = container.clientWidth; } offsets = me.getOffsetsTo(container); return { y: me.calcScrollPos(offsets[1] + scrollY, dom.offsetHeight, scrollY, clientHeight, align.y), x: me.calcScrollPos(offsets[0] + scrollX, dom.offsetWidth, scrollX, clientWidth, align.x) }; }, calcScrollPos: function(start, size, viewStart, viewSize, align) { var end = start + size, viewEnd = viewStart + viewSize, force = align && !endsQuestionRe.test(align), ret = viewStart; if (!force) { if (align) { align = align.slice(0, -1); } if (size > viewSize || start < viewStart) { align = align || 'start'; force = true; } else if (end > viewEnd) { align = align || 'end'; force = true; } } if (force) { if (align === 'start') { ret = start; } else if (align === 'center') { ret = Math.max(0, start - Math.floor((viewSize / 2))); } else if (align === 'end') { ret = Math.max(0, end - viewSize); } } return ret; }, getScrollLeft: function() { var dom = this.dom; if (dom === DOC || dom === DOC.body) { return this.getScroll().left; } else { return dom.scrollLeft; } }, getScrollTop: function() { var dom = this.dom; if (dom === DOC || dom === DOC.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); }, getCaretPos: function() { var dom = this.dom, pos, selection; if (inputTypeSelectionSupported.test(dom.type)) { pos = dom.selectionStart; selection = (typeof pos !== 'number') && this.getTextSelection(); if (selection) { pos = selection[0]; } } else { Ext.raise('Input type of "' + dom.type + '" does not support selectionStart'); } return pos; }, setCaretPos: function(pos) { this.selectText(pos, pos); }, getTextSelection: function() { var dom = this.dom; if (inputTypeSelectionSupported.test(dom.type)) { return [ dom.selectionStart, dom.selectionEnd, dom.selectionDirection ]; } else { Ext.raise('Input type of "' + this.dom.type + '" does not support selectionStart, selectionEnd and selectionDirection'); return []; } }, selectText: function(start, end, direction) { var me = this, range, dom = me.dom, len; if (dom && inputTypeSelectionSupported.test(dom.type)) { start = start || 0; len = dom.value.length; if (end === undefined) { end = len; } direction = selectDir[direction] || direction || 'forward'; if (dom.setSelectionRange) { dom.setSelectionRange(start, end, direction); } else if (dom.createTextRange) { if (start > end) { start = end; } range = dom.createTextRange(); range.moveStart('character', start); range.moveEnd('character', -(len - end)); range.select(); } } else if (!inputTypeSelectionSupported.test(dom.type)) { Ext.raise('Input type of "' + dom.type + '" does not support setSelectionRange'); } return me; }, getTop: function(local) { return local ? this.getLocalY() : this.getY(); }, getTouchAction: function() { return Ext.dom.TouchAction.get(this.dom); }, 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, body = DOC.body, x = 0, y = 0, bodyRect, rect; if (dom !== DOC && dom !== body) { try { bodyRect = body.getBoundingClientRect(); rect = dom.getBoundingClientRect(); x = rect.left - bodyRect.left; y = rect.top - bodyRect.top; } catch (ex) {} } return [ round(x), round(y) ]; }, getY: function() { return this.getXY()[1]; }, getZIndex: function() { return parseInt(this.getStyle('z-index'), 10); }, hasCls: function(name) { var classMap = this.getClassMap(); return classMap.hasOwnProperty(name); }, hide: function() { return this.setVisible(false); }, 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; }, indexOf: function(childEl) { var children = this.dom, c = childEl && Ext.getDom(childEl); children = children && children.childNodes; return (c && children) ? Array.prototype.indexOf.call(children, c) : -1; }, 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(DOC.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 (!child.nodeType) { return false; } 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)); }; })(), isScrollable: function() { var dom = this.dom; return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth; }, isStyle: function(style, val) { return this.getStyle(style) === val; }, isVisible: function(deep, mode) { var dom = this.dom, visible = true, end; if (!dom) { return false; } mode = mode || 3; if (!visFly) { visFly = new Ext.dom.Fly(); } for (end = dom.ownerDocument.documentElement; dom !== end; dom = dom.parentNode) { if (!dom || dom.nodeType === 11) { visible = false; } if (visible) { visFly.attach(dom); if (mode & 1) { visible = !visFly.isStyle(DISPLAY, NONE); } if (visible && (mode & 2)) { visible = !visFly.isStyle(VISIBILITY, HIDDEN); } } if (!visible || !deep) { break; } } return visible; }, 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; }, measure: function(dimension) { var me = this, dom = me.dom, includeWidth = dimension !== 'h', includeHeight = dimension !== 'w', width = 0, height = 0, addPadding = !Ext.supports.ComputedSizeIncludesPadding, style, rect, offsetParent; if (dom.nodeName === 'BODY') { height = includeHeight && Element.getViewportHeight(); width = includeWidth && Element.getViewportWidth(); } else { offsetParent = dom.offsetParent; style = dom.ownerDocument.defaultView.getComputedStyle(dom, null); addPadding |= style.boxSizing === 'content-box'; if (offsetParent !== null || style.position === 'fixed') { if (includeHeight) { height = toFloat(style.height); if (addPadding) { height += toFloat(style.paddingTop) + toFloat(style.paddingBottom) + toFloat(style.borderTopWidth) + toFloat(style.borderBottomWidth); } } if (includeWidth) { width = toFloat(style.width); if (addPadding) { width += toFloat(style.paddingLeft) + toFloat(style.paddingRight) + toFloat(style.borderLeftWidth) + toFloat(style.borderRightWidth); } } } } rect = dimension ? null : { width: width, height: height }; return dimension ? (includeWidth ? width : height) : rect; }, measureContent: function(dimension) { var me = this, includeWidth = dimension !== 'h', size = me.measure(dimension), h = dimension ? size : size.height, w = dimension ? size : size.width; if (dimension !== 'w') { h -= me.getBorderWidth('tb') + me.getPadding('tb'); } if (includeWidth) { w -= me.getBorderWidth('lr') + me.getPadding('lr'); } return dimension ? (includeWidth ? w : h) : { width: w, height: h }; }, 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() { Ext.undefer(timer); }, destroy: function() { Ext.undefer(timer); if (!me.destroyed) { me.un(listeners); } } }; me.on(listeners); return listeners; }, next: function(selector, returnDom) { return this.matchNode('nextSibling', 'nextSibling', selector, returnDom); }, parent: function(selector, returnDom) { return this.matchNode('parentNode', 'parentNode', selector, returnDom); }, peekData: function() { var dom = this.dom; return dom && dom._extData || null; }, 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) { return this.replaceCls(names, null, prefix, suffix); }, repaint: function() { var me = this; me.addCls(Ext.baseCSSPrefix + 'repaint'); if (!me.repaintTimer) { me.repaintTimer = Ext.defer(function() { me.repaintTimer = null; if (me.dom) { me.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.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(remove, add, prefix, suffix) { var me = this, added = 0, removed = 0, rem = remove, data = (add || remove) && me.getData(), list, map, i, n, name; if (data) { list = data.classList; map = data.classMap; add = add ? ((typeof add === 'string') ? add.split(spacesRe) : add) : EMPTY; rem = rem ? ((typeof rem === 'string') ? rem.split(spacesRe) : rem) : EMPTY; prefix = prefix || ''; if (prefix && prefix[prefix.length - 1] !== '-') { prefix += '-'; } suffix = suffix || ''; if (suffix && suffix[0] !== '-') { suffix = '-' + suffix; } for (i = 0 , n = rem.length; i < n; i++) { if (!(name = rem[i])) { continue; } name = prefix + name + suffix; if (spacesRe.test(name)) { Ext.raise('Class names in arrays must not contain spaces'); } if (map[name]) { delete map[name]; ++removed; } } for (i = 0 , n = add.length; i < n; i++) { if (!(name = add[i])) { continue; } name = prefix + name + suffix; if (spacesRe.test(name)) { Ext.raise('Class names in arrays must not contain spaces'); } if (!map[name]) { map[name] = true; if (!removed) { list.push(name); ++added; } } } if (removed) { me.setClassMap(map, true); } else if (added) { me.dom.className = list.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; 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.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; }, setClassMap: function(classMap, keep) { var data = this.getData( false), classList; if (data) { classMap = (keep && classMap) || Ext.apply({}, classMap); data.classMap = classMap; data.classList = classList = Ext.Object.getKeys(classMap); data.isSynchronized = true; this.dom.className = classList.join(' '); } }, setCls: function(className) { var me = this, elementData = me.getData( false), i, ln, map, classList; if (typeof className === 'string') { className = className.split(spacesRe); } elementData.classList = classList = className.slice(); elementData.classMap = map = {}; for (i = 0 , ln = classList.length; i < ln; i++) { map[classList[i]] = true; } me.dom.className = classList.join(' '); }, setDisplayed: function(value) { var me = this; if (typeof value === "boolean") { value = value ? me._getDisplay() : NONE; } me.setStyle(DISPLAY, value); if (me.shadow || me.shim) { me.setUnderlaysVisible(value !== NONE); } return me; }, 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; } return this; }, 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 = ''; 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 = ''; 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; }, setOpacity: function(opacity) { var me = this; if (me.dom) { me.setStyle('opacity', opacity); } return me; }, 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; } if (width !== undefined) { style.width = Element.addUnits(width); } if (height !== undefined) { style.height = Element.addUnits(height); } if (me.shadow || me.shim) { me.syncUnderlays(); } 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) { 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; }, setTouchAction: function(touchAction) { Ext.dom.TouchAction.set(this.dom, touchAction); }, 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 && mode !== 4 && mode !== 5) { Ext.raise("visibilityMode must be one of the following: " + "Ext.Element.DISPLAY, Ext.Element.VISIBILITY, Ext.Element.OFFSETS, " + "Ext.Element.CLIP, or Element.OPACITY"); } this.getData().visibilityMode = mode; return this; }, setVisible: function(visible) { var me = this, mode = me.getVisibilityMode(), addOrRemove = visible ? 'removeCls' : 'addCls'; switch (mode) { case Element.DISPLAY: me.removeCls([ visibilityCls, offsetsCls, clipCls, opacityCls ]); me[addOrRemove](displayCls); break; case Element.VISIBILITY: me.removeCls([ displayCls, offsetsCls, clipCls, opacityCls ]); me[addOrRemove](visibilityCls); break; case Element.OFFSETS: me.removeCls([ visibilityCls, displayCls, clipCls, opacityCls ]); me[addOrRemove](offsetsCls); break; case Element.CLIP: me.removeCls([ visibilityCls, displayCls, offsetsCls, opacityCls ]); me[addOrRemove](clipCls); break; case Element.OPACITY: me.removeCls([ visibilityCls, displayCls, offsetsCls, clipCls ]); me[addOrRemove](opacityCls); break; } if (me.shadow || me.shim) { me.setUnderlaysVisible(visible); } if (!visible && me.$ripples) { me.destroyAllRipples(); } 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 = ''; 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() { return this.setVisible(true); }, swallowEvent: function(eventName, preventDefault) { var me = this, e, eLen, listeners = { destroyable: true }, fn = function(e) { e.stopPropagation(); if (preventDefault) { e.preventDefault(); } }; if (Ext.isArray(eventName)) { eLen = eventName.length; for (e = 0; e < eLen; e++) { listeners[eventName[e]] = fn; } } else { listeners[eventName] = fn; } return me.on(listeners); }, 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( false); 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, state) { if (state == null) { state = !this.hasCls(className); } return state ? 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) { x = Math.round(x); y = Math.round(y); z = Math.round(z); this.dom.style[transformStyleName] = 'translate3d(' + (x || 0) + 'px, ' + (y || 0) + 'px, ' + (z || 0) + 'px)'; }; }(), unwrap: function() { var dom = this.dom, parentNode = dom.parentNode, activeElement = (activeElFly || (activeElFly = new Ext.dom.Fly())).attach(Ext.Element.getActiveElement()), grandparentNode, cached, resumeFocus, tabIndex; grannyFly = grannyFly || new Ext.dom.Fly(); cached = Ext.cache[activeElement.dom.id]; if (cached) { activeElement = cached; } if (this.contains(activeElement)) { if (cached) { cached.suspendFocusEvents(); } resumeFocus = true; } if (parentNode) { grandparentNode = parentNode.parentNode; if (resumeFocus) { tabIndex = grandparentNode.getAttribute('tabIndex'); grannyFly.attach(grandparentNode); grannyFly.set({ tabIndex: -1 }); grannyFly.suspendFocusEvents(); grannyFly.focus(); } grandparentNode.insertBefore(dom, parentNode); grandparentNode.removeChild(parentNode); } else { grandparentNode = DOC.createDocumentFragment(); grandparentNode.appendChild(dom); } if (resumeFocus) { if (cached) { cached.focus(); cached.resumeFocusEvents(); } else { activeElement.focus(); } if (grannyFly) { grannyFly.resumeFocusEvents(); grannyFly.set({ tabIndex: tabIndex }); } } 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, result = Ext.DomHelper.insertBefore(dom, config || { tag: "div" }, !returnDom), newEl = (wrapFly || (wrapFly = new Ext.dom.Fly())).attach(Ext.getDom(result)), target = newEl, activeElement = (activeElFly || (activeElFly = new Ext.dom.Fly())).attach(Ext.Element.getActiveElement()), cached, resumeFocus, tabIndex; cached = Ext.cache[activeElement.dom.id]; if (cached) { activeElement = cached; } if (selector) { target = newEl.selectNode(selector, returnDom); } if (me.contains(activeElement)) { if (cached) { cached.suspendFocusEvents(); } tabIndex = Ext.getDom(newEl).getAttribute('tabIndex'); newEl.set({ tabIndex: -1 }); newEl.suspendFocusEvents(); newEl.focus(); resumeFocus = true; } (target.dom || target).appendChild(dom); if (resumeFocus) { if (cached) { cached.focus(); cached.resumeFocusEvents(); } else { activeElement.focus(); } newEl.resumeFocusEvents(); newEl.set({ tabIndex: tabIndex }); } return result; }, isFocusable: function(skipVisibility) { 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 && (skipVisibility || this.isVisible(true)); } return focusable; }, isInputField: function() { var dom = this.dom, contentEditable = dom.contentEditable; if ((Ext.Element.inputTags[dom.tagName] && dom.type !== 'button') || (contentEditable === '' || contentEditable === 'true')) { return true; } return false; }, isTabbable: function(includeHidden) { 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 && (includeHidden || ((!this.component || this.component.isVisible(true)) && this.isVisible(true))); } return tabbable; }, ripplingCls: Ext.baseCSSPrefix + 'rippling', ripplingTransitionCls: Ext.baseCSSPrefix + 'ripple-transition', ripplingUnboundCls: Ext.baseCSSPrefix + 'rippling-unbound', rippleBubbleCls: Ext.baseCSSPrefix + 'ripple-bubble', rippleContainerCls: Ext.baseCSSPrefix + 'ripple-container', rippleWrapperCls: Ext.baseCSSPrefix + 'ripple-wrapper', noRippleDisplayMap: { table: 1, 'table-row': 1, 'table-row-group': 1 }, noRippleTagMap: { TABLE: 1, TR: 1, TBODY: 1 }, ripple: function(event, options) { if (options === true || !options) { options = {}; } else if (Ext.isString(options)) { options = { color: options }; } var me = this, rippleParent = Ext.isString(options.delegate) ? me.down(options.delegate) : me, rippleMeasureEl = Ext.isString(options.measureSelector) ? me.down(options.measureSelector) : null, color = window.getComputedStyle(rippleParent.dom).color, unbound = options.bound === false, position = options.position, ripplingCls = me.ripplingCls, ripplingTransitionCls = me.ripplingTransitionCls, ripplingUnboundCls = me.ripplingUnboundCls, rippleBubbleCls = me.rippleBubbleCls, rippleContainerCls = me.rippleContainerCls, rippleWrapperCls = me.rippleWrapperCls, offset, width, height, rippleDiameter, center, measureElWidth, measureElHeight, rippleSize, pos, posX, posY, rippleWrapper, rippleContainer, rippleBubble, rippleDestructor, rippleClearFn, rippleDestructionTimer, rippleBox, unboundEl, unboundElData, timeout; if (rippleParent) { offset = rippleParent.getXY(); width = rippleParent.getWidth(); height = rippleParent.getHeight(); timeout = rippleParent.$rippleClearTimeout; if (timeout) { rippleParent.$rippleClearTimeout = Ext.undefer(timeout); } if (rippleMeasureEl) { measureElWidth = rippleMeasureEl.getWidth(); measureElHeight = rippleMeasureEl.getHeight(); rippleDiameter = Math.max(measureElWidth, measureElHeight); } else { rippleDiameter = width > height ? width : height; } if (options.diameterLimit === undefined || options.diameterLimit === true) { rippleDiameter = Math.min(rippleDiameter, Element.maxRippleDiameter); } else if (options.diameterLimit && options.diameterLimit !== false && options.diameterLimit !== 0) { rippleDiameter = Math.min(rippleDiameter, options.diameterLimit); } center = [ offset[0] + width / 2, offset[1] + height / 2 ]; if (unbound) { if (options.fit !== false) { rippleSize = rippleDiameter * 2.15; rippleBox = rippleParent.getRegion(); rippleBox.setPosition(rippleBox.getCenter()).setSize(rippleSize).translateBy(-rippleSize / 2, -rippleSize / 2); unboundEl = me.up(function(candidate) { var fly = Ext.fly(candidate, 'ripple'); return !(candidate.tagName in me.noRippleTagMap) && !(fly.getStyle('display') in me.noRippleDisplayMap) && (fly.getRegion().contains(rippleBox)); }) || Ext.getBody(); } else { unboundEl = rippleParent; } } if (Ext.isString(event)) { options.color = event; event = null; } else if (event && !event.isEvent) { event = new Ext.event.Event(event); } if (event && event.isEvent) { if (event.browserEvent.$preventRipple) { return; } position = event.getXY(); event.browserEvent.$preventRipple = true; } pos = (!unbound && !options.centered && position) || center; posX = pos[0] - offset[0] - (rippleDiameter / 2); posY = pos[1] - offset[1] - (rippleDiameter / 2); rippleParent.addCls(ripplingTransitionCls); if (!unbound) { rippleParent.addCls(ripplingCls); rippleContainer = rippleParent.child('.' + rippleContainerCls); } else { unboundElData = unboundEl.getData(); rippleWrapper = unboundElData.rippleWrapper; if (!rippleWrapper) { unboundElData.rippleWrapper = rippleWrapper = unboundEl.insertFirst({ style: 'position: absolute; top: 0; left: 0', cls: rippleWrapperCls + ' ' + ripplingCls + ' ' + ripplingUnboundCls }); } } if (!rippleContainer) { if (unbound) { rippleContainer = rippleWrapper.append({ cls: rippleContainerCls }); rippleContainer.setXY(offset); } else { rippleContainer = rippleParent.append({ cls: rippleContainerCls }); } } rippleBubble = rippleContainer.append({ cls: rippleBubbleCls }); if (options.color !== 'default') { rippleBubble.setStyle('backgroundColor', options.color || color); } rippleBubble.setWidth(rippleDiameter); rippleBubble.setHeight(rippleDiameter); rippleBubble.setTop(posY); rippleBubble.setLeft(posX); rippleClearFn = function() { if (!rippleParent.destroyed) { rippleParent.$rippleClearTimeout = Ext.defer(function() { rippleParent.removeCls([ ripplingCls, ripplingTransitionCls ]); rippleParent.$rippleClearTimeout = null; }, 50); } }; rippleDestructor = function() { var ripple, timeout; rippleBubble.destroy(); if (me.$ripples) { delete me.$ripples[rippleBubble.id]; } timeout = rippleParent.$rippleClearTimeout; if (timeout) { rippleParent.$rippleClearTimeout = Ext.undefer(timeout); } if (unbound) { rippleContainer.destroy(); ripple = rippleWrapper.child('.' + rippleContainerCls); if (!ripple) { unboundElData.rippleWrapper = null; rippleWrapper.destroy(); rippleClearFn(); } } else { ripple = rippleContainer.child('.' + rippleBubbleCls); if (!ripple) { rippleContainer.destroy(); rippleClearFn(); } } }; rippleDestructionTimer = Ext.defer(rippleDestructor, options.destroyTime || 1000, me); if (!me.$ripples) { me.$ripples = {}; } me.$ripples[rippleBubble.id] = { timerId: rippleDestructionTimer, destructor: rippleDestructor }; rippleBubble.addCls(Ext.baseCSSPrefix + 'ripple'); } }, destroyAllRipples: function() { var me = this, rippleEl, ripple; for (rippleEl in me.$ripples) { ripple = me.$ripples[rippleEl]; Ext.undefer(ripple.timerId); if (ripple.destructor) { ripple.destructor(); } } me.$ripples = null; }, privates: { findTabbableElements: function(options) { var skipSelf, skipChildren, excludeRoot, includeSaved, includeHidden, dom = this.dom, cAttr = Ext.Element.tabbableSavedCounterAttribute, selection = [], idx = 0, nodes, node, fly, i, len, tabIndex; if (!dom) { return selection; } if (options) { skipSelf = options.skipSelf; skipChildren = options.skipChildren; excludeRoot = options.excludeRoot; includeSaved = options.includeSaved; includeHidden = options.includeHidden; } excludeRoot = excludeRoot && Ext.getDom(excludeRoot); if (excludeRoot && excludeRoot.contains(dom)) { return selection; } if (!skipSelf && ((includeSaved && dom.hasAttribute(cAttr)) || this.isTabbable(includeHidden))) { selection[idx++] = dom; } if (skipChildren) { return selection; } nodes = dom.querySelectorAll(Ext.Element.tabbableSelector); len = nodes.length; if (!len) { return selection; } fly = new Ext.dom.Fly(); for (i = 0; i < len; i++) { node = nodes[i]; tabIndex = +node.getAttribute('tabIndex'); if (((includeSaved && node.hasAttribute(cAttr)) || (!(tabIndex < 0) && fly.attach(node).isTabbable(includeHidden))) && !(excludeRoot && (excludeRoot === node || excludeRoot.contains(node)))) { selection[idx++] = node; } } return selection; }, saveTabbableState: function(options) { var counterAttr = Ext.Element.tabbableSavedCounterAttribute, savedAttr = Ext.Element.tabbableSavedValueAttribute, counter, nodes, node, i, len; if (!options || options.includeSaved == null) { options = Ext.Object.chain(options || null); options.includeSaved = true; } nodes = this.findTabbableElements(options); for (i = 0 , len = nodes.length; i < len; i++) { node = nodes[i]; counter = +node.getAttribute(counterAttr); if (counter > 0) { node.setAttribute(counterAttr, ++counter); } else { if (node.hasAttribute('tabIndex')) { node.setAttribute(savedAttr, node.getAttribute('tabIndex')); } else { node.setAttribute(savedAttr, 'none'); } node.setAttribute('tabIndex', '-1'); node.setAttribute(counterAttr, '1'); } } return nodes; }, restoreTabbableState: function(options) { var dom = this.dom, counterAttr = Ext.Element.tabbableSavedCounterAttribute, savedAttr = Ext.Element.tabbableSavedValueAttribute, nodes = [], skipSelf = options && options.skipSelf, skipChildren = options && options.skipChildren, reset = options && options.reset, idx, counter, node, i, len; if (!dom) { return this; } if (!skipChildren) { nodes = Ext.Array.from(dom.querySelectorAll('[' + counterAttr + ']')); } if (!skipSelf) { nodes.unshift(dom); } for (i = 0 , len = nodes.length; i < len; i++) { node = nodes[i]; if (!node.hasAttribute(counterAttr) || !node.hasAttribute(savedAttr)) { continue; } counter = +node.getAttribute(counterAttr); if (!reset && counter > 1) { node.setAttribute(counterAttr, --counter); continue; } idx = node.getAttribute(savedAttr); if (idx === 'none') { node.removeAttribute('tabIndex'); } else { node.setAttribute('tabIndex', idx); } node.removeAttribute(savedAttr); node.removeAttribute(counterAttr); } return nodes; }, setTabIndex: function(tabIndex) { var dom = this.dom, savedAttr = Ext.Element.tabbableSavedValueAttribute; if (dom.hasAttribute(savedAttr)) { if (tabIndex == null) { dom.setAttribute(savedAttr, 'none'); dom.removeAttribute('tabIndex'); } else { dom.setAttribute(savedAttr, tabIndex); } } else { if (tabIndex == null) { dom.removeAttribute('tabIndex'); } else { dom.setAttribute('tabIndex', tabIndex); } } }, doAddListener: function(eventName, fn, scope, options, order, caller, manager) { var me = this, originalName = eventName, observableDoAddListener, additiveEventName, translatedEventName; eventName = Ext.canonicalEventName(eventName); if (!me.blockedEvents[eventName]) { observableDoAddListener = me.mixins.observable.doAddListener; options = options || {}; 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; if (manager) { options.managedName = originalName; } eventName = translatedEventName; } } if (observableDoAddListener.call(me, eventName, fn, scope, options, order, caller, manager)) { if (me.longpressEvents[eventName] && (++me.longpressListenerCount === 1)) { me.on('MSHoldVisual', 'preventMsHoldVisual', me); } } if (manager && translatedEventName) { delete options.managedName; } delete options.type; } }, doRemoveListener: function(eventName, fn, scope) { var me = this, observableDoRemoveListener, translatedEventName, additiveEventName, removed; eventName = Ext.canonicalEventName(eventName); if (!me.blockedEvents[eventName]) { observableDoRemoveListener = me.mixins.observable.doRemoveListener; additiveEventName = me.additiveEvents[eventName]; if (additiveEventName) { eventName = additiveEventName; observableDoRemoveListener.call(me, eventName, fn, scope); } translatedEventName = me.eventMap[eventName]; if (translatedEventName) { removed = observableDoRemoveListener.call(me, translatedEventName, fn, scope); } removed = observableDoRemoveListener.call(me, eventName, fn, scope) || removed; if (removed) { if (me.longpressEvents[eventName] && !--me.longpressListenerCount) { me.un('MSHoldVisual', 'preventMsHoldVisual', me); } } } }, _initEvent: function(eventName) { return (this.events[eventName] = new Ext.dom.ElementEvent(this, eventName)); }, _getDisplay: function() { var data = this.getData(), display = data[ORIGINALDISPLAY]; if (display === undefined) { data[ORIGINALDISPLAY] = display = ''; } return display; }, _getPublisher: function(eventName, noTranslate) { var Publisher = Ext.event.publisher.Publisher, publisher = Publisher.publishersByEvent[eventName], isNative = noTranslate && !Ext.event.Event.gestureEvents[eventName]; if (isNative || !publisher || (this.dom === window && eventName === 'resize')) { publisher = Publisher.publishers.dom; } return publisher; }, isFocusSuspended: function() { var data = this.peekData(); return data && data.suspendFocusEvents; }, preventMsHoldVisual: function(e) { e.preventDefault(); }, suspendFocusEvents: function() { if (!this.isFly) { this.suspendEvent('focus', 'blur'); } this.getData().suspendFocusEvents = true; }, resumeFocusEvents: function() { function resumeFn() { var data; if (!this.destroyed) { data = this.getData(); if (data) { data.suspendFocusEvents = false; } if (!this.isFly) { this.resumeEvent('focus', 'blur'); } } } if (!this.destroyed && this.getData().suspendFocusEvents) { if (Ext.isIE && !this.isFly) { this.resumeFocusEventsTimer = Ext.asap(resumeFn, this); } else { resumeFn.call(this); } } } }, deprecated: { '5.0': { methods: { getHTML: 'getHtml', 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 }; } }, isTransparent: function(prop) { var value = this.getStyle(prop); return value ? transparentRe.test(value) : false; }, purgeAllListeners: 'clearListeners', removeAllListeners: 'clearListeners', setHTML: 'setHtml' } } } }; }, function(Element) { var DOC = document, docEl = DOC.documentElement, 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; prototype._init(Element); delete prototype._init; Ext.id = function(obj, prefix) { var el = obj && 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[mouseover] = 'pointerover'; eventMap[mouseout] = 'pointerout'; eventMap[mouseenter] = 'pointerenter'; if (!Ext.isIE11) { 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[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.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.styleHooks.opacity = { name: 'opacity', afterSet: function(dom, value, el) { var shadow = el.shadow; if (shadow) { shadow.setOpacity(value); } } }; prototype.getTrueXY = prototype.getXY; Ext.getViewportHeight = Element.getViewportHeight; Ext.getViewportWidth = Element.getViewportWidth; 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 typeof el === 'string' ? Ext.getElementById(el) : 'dom' in el ? el.dom : 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); Ext._bodyEl.skipGarbageCollection = true; } return Ext._bodyEl; }, getHead: function() { if (!Ext._headEl) { Ext._headEl = Ext.get(DOC.head || DOC.getElementsByTagName('head')[0]); Ext._headEl.skipGarbageCollection = true; } return Ext._headEl; }, getDoc: function() { if (!Ext._docEl) { Ext._docEl = Ext.get(DOC); Ext._docEl.skipGarbageCollection = true; } return Ext._docEl; }, getWin: function() { if (!Ext._winEl) { Ext._winEl = Ext.get(window); Ext._winEl.skipGarbageCollection = true; } 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 === null && ((Ext.isIE8 ? DOC.all[dom.id] : DOC.getElementById(dom.id)) !== dom) && !(Ext.detachedBodyEl && Ext.detachedBodyEl.isAncestor(dom)))); }; Ext.onInternalReady(function() { var bodyCls = [], theme; Ext.getDoc().on('selectstart', function(ev, dom) { var selectableCls = Element.selectableCls, unselectableCls = Element.unselectableCls, tagName = dom && dom.tagName, el = new Ext.dom.Fly(); tagName = tagName && tagName.toLowerCase(); if (tagName === 'input' || tagName === 'textarea') { return; } while (dom && dom.nodeType === 1 && dom !== DOC.documentElement) { el.attach(dom); if (el.hasCls(selectableCls)) { return; } if (el.hasCls(unselectableCls)) { ev.stopEvent(); return; } dom = dom.parentNode; } }); if (Ext.os.is.Android || (Ext.os.is.Windows && Ext.supports.Touch)) { var win = Ext.getWin(); Element._documentWidth = Element._viewportWidth = docEl.clientWidth; Element._documentHeight = Element._viewportHeight = docEl.clientHeight; win.on({ focusin: '_onWindowFocusChange', focusout: '_onWindowFocusChange', pointerup: '_onWindowFocusChange', capture: true, delegated: false, delay: 1, scope: Element }); win.on({ resize: '_onWindowResize', priority: 2000, scope: Element }); } 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.isIE10p) { bodyCls.push(Ext.baseCSSPrefix + 'ie10p'); } if (Ext.isIE11) { bodyCls.push(Ext.baseCSSPrefix + 'ie11'); } if (Ext.isEdge) { bodyCls.push(Ext.baseCSSPrefix + 'edge'); } 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.isSafari9) { bodyCls.push(Ext.baseCSSPrefix + 'safari9'); } if (Ext.isSafari10) { bodyCls.push(Ext.baseCSSPrefix + 'safari10'); } if (Ext.isSafari11) { bodyCls.push(Ext.baseCSSPrefix + 'safari11'); } if (Ext.isSafari && Ext.browser.version.isLessThan(9)) { bodyCls.push(Ext.baseCSSPrefix + 'safari8m'); } if (Ext.isChrome) { bodyCls.push(Ext.baseCSSPrefix + 'chrome'); } if (Ext.isMac) { bodyCls.push(Ext.baseCSSPrefix + 'mac'); } if (Ext.isWindows) { bodyCls.push(Ext.baseCSSPrefix + 'windows'); } 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'); } if (Ext.os.deviceType) { bodyCls.push(Ext.baseCSSPrefix + Ext.os.deviceType.toLowerCase()); } if (Ext.os.is.BlackBerry) { bodyCls.push(Ext.baseCSSPrefix + 'bb'); if (Ext.browser.userAgent.match(/Kbd/gi)) { bodyCls.push(Ext.baseCSSPrefix + 'bb-keyboard'); } } if (Ext.os.is.iOS && Ext.isSafari) { bodyCls.push(Ext.baseCSSPrefix + 'mobile-safari'); } if (Ext.os.is.iOS && Ext.browser.is.WebView && !Ext.browser.is.Standalone) { bodyCls.push(Ext.baseCSSPrefix + 'ios-native'); } if (Ext.supports.FlexBoxBasisBug) { bodyCls.push(Ext.baseCSSPrefix + 'has-flexbasis-bug'); } Ext.getBody().addCls(bodyCls); theme = Ext.theme; if (theme && theme.getDocCls) { Ext.fly(document.documentElement).addCls(theme.getDocCls()); } }, null, { priority: 1500 }); }); Ext.define('Ext.GlobalEvents', { extend: Ext.mixin.Observable, alternateClassName: 'Ext.globalEvents', observableType: 'global', singleton: true, resizeBuffer: 100, idleEventMask: { mousemove: 1, touchmove: 1, pointermove: 1, MSPointerMove: 1, unload: 1 }, windowListeners: { resize: { fn: 'fireResize' } }, constructor: function() { var me = this; me.callParent(); Ext.onInternalReady(function() { me.attachListeners(); }); }, setPressedComponent: function(component, e) { var me = this, pressedComponent = me.pressedComponent; if (pressedComponent && pressedComponent.onRelease) { pressedComponent.onRelease(e); } me.pressedComponent = component; if (component) { me.pressedScrollStart = Ext.on({ scrollstart: function() { me.setPressedComponent(null, e); }, destroyable: true }); } else { me.pressedScrollStart = Ext.destroy(me.pressedScrollStart); } }, attachListeners: function() { var me = this, win = Ext.getWin(), winListeners = me.windowListeners; me.onlineState = Ext.isOnline(); me.curHeight = Ext.Element.getViewportHeight(); me.curWidth = Ext.Element.getViewportWidth(); win.on({ scope: me, online: 'handleOnlineChange', offline: 'handleOnlineChange' }); me.fireResize.$skipTimerCheck = true; if (winListeners) { winListeners.scope = me; if (Ext.isModern) { winListeners.resize.onFrame = true; } else { winListeners.resize.buffer = me.resizeBuffer; } win.on(winListeners); } Ext.getDoc().on({ touchstart: 'fireMouseDown', mousedown: 'fireMouseDown', mouseup: 'fireMouseUp', touchend: 'fireMouseUp', drop: 'fireMouseUp', dragend: 'fireMouseUp', scope: me }); }, fireMouseDown: function(e) { this.fireEvent('mousedown', e); Ext.ComponentManager.handleDocumentMouseDown(e); }, fireMouseUp: function(e) { this.fireEvent('mouseup', e); this.setPressedComponent(null, e); }, 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; if (me.hasListeners.resize) { me.fireEvent('resize', w, h); } } }, handleOnlineChange: function() { var online = Ext.isOnline(); if (online !== this.onlineState) { this.onlineState = online; this.fireEvent('onlinechange', online); } } }, function(GlobalEvents) { Ext.on = function() { return GlobalEvents.addListener.apply(GlobalEvents, arguments); }; Ext.un = function() { return GlobalEvents.removeListener.apply(GlobalEvents, arguments); }; Ext.fireEvent = function() { return GlobalEvents.fireEvent.apply(GlobalEvents, arguments); }; Ext.fireIdle = function() { if (GlobalEvents.hasListeners.idle && !Ext._suppressIdle) { GlobalEvents.fireEventArgs('idle'); } Ext._suppressIdle = false; }; Ext._suppressIdle = false; }); Ext.define('Ext.Glyph', { isGlyph: true, constructor: function(glyph) { glyph && this.setGlyph(glyph); }, setGlyph: function(glyph) { var glyphParts; this.glyphConfig = glyph; if (typeof glyph === 'string') { glyphParts = glyph.split('@'); if (isNaN(glyph = isNaN(glyphParts[0]) ? parseInt('0' + glyphParts[0], 16) : parseInt(glyphParts[0], 10)) || !glyph) { glyph = glyphParts[0].charCodeAt(0); } this.fontFamily = glyphParts[1] || Ext._glyphFontFamily; } else { this.fontFamily = Ext._glyphFontFamily; } this.codepoint = glyph; this.character = Ext.String.fromCodePoint(this.codepoint); return this; }, getStyle: function() { return { 'font-family': this.fontFamily }; }, isEqual: function(other) { return other && other.isGlyph && other.codepoint === this.codepoint && other.fontFamily === this.fontFamily; }, statics: (function() { var instance; return { fly: function(glyph) { return glyph.isGlyph ? glyph : (instance || (instance = new Ext.Glyph())).setGlyph(glyph); } }; })() }); Ext.USE_NATIVE_JSON = true; 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 (typeof o.toJSON === 'function') { return doEncode(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 || val.isInstance) { 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.raise({ sourceClass: "Ext.JSON", sourceMethod: "decode", msg: "You're trying to decode an invalid JSON String: " + json }); } }; me.encodeMSDate = encodeMSDate; if (!Ext.util) { Ext.util = {}; } Ext.util.JSON = me; Ext.encode = me.encode; Ext.decode = me.decode; })()); 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.getRefOwner(), isContainer = me.isContainer, parent, inheritedStateInner, getInner, ownerLayout; if (!inheritedState || inheritedState.invalid) { parent = me.getRefOwner(); ownerLayout = me.ownerLayout; if (ownerCt) { getInner = ownerLayout ? ownerLayout === ownerCt.layout : true; } 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; }, 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.isOwner) { ret = me.getRefOwner(); } 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; }, lookupNameHolder: function(skipThis) { return this.getInheritedConfig('nameHolder', skipThis !== false) || null; }, lookupReferenceHolder: function(skipThis) { return this.getInheritedConfig('referenceHolder', skipThis !== false) || null; }, getRefOwner: function() { var me = this; return me.ownerCmp || me.ownerCt || me.parent || me.$initParent || me.floatParent; }, bubble: function(fn, scope, args) { for (var target = this; target; target = target.getRefOwner()) { if (fn.apply(scope || target, args || [ target ]) === false) { break; } } }, isDescendantOf: function(ancestor) { return ancestor ? ancestor.isAncestor(this) : false; }, isAncestor: function(possibleDescendant) { while (possibleDescendant) { if (possibleDescendant.getRefOwner() === this) { return true; } possibleDescendant = possibleDescendant.getRefOwner(); } return false; }, invalidateInheritedState: function() { var inheritedState = this.inheritedState; if (inheritedState) { inheritedState.invalid = true; delete this.inheritedState; } }, privates: { _fixName: function() { var me = this, owner; if (me.name) { owner = me.lookupNameHolder(); if (owner && !owner.destroyed) { owner.attachNameRef(me); } } }, _fixReference: function() { var me = this, refHolder; if (me.reference) { refHolder = me.lookupReferenceHolder(); if (refHolder) { refHolder.attachReference(me); } } }, onInheritedAdd: function(parent, instanced) { var me = this; if (me.inheritedState && instanced) { me.invalidateInheritedState(); } if (me.name || me.reference) { Ext.ComponentManager.markReferencesDirty(); } }, onInheritedRemove: function(destroying) { var me = this; if (me.name || me.reference) { Ext.ComponentManager.markReferencesDirty(); } if (me.inheritedState && !destroying) { me.invalidateInheritedState(); } } } }, 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); } }, 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, nameable: false, shareableName: false, reference: null, validRefRe: /^[a-z_][a-z0-9_]*$/i, getReference: function() { return this.reference; }, initInheritedState: function(inheritedState) { var me = this, reference = me.reference, 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; } }, isBound: function(name) { var bind = this.getBind(); return !!(bind && (bind[name || this.defaultBindProperty])); }, 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, state = me.publishedState, binds = me.getBind(), binding = binds && property && binds[property], count = 0, name, publishes, vm, path; if (!(arguments.length === 0 || arguments.length === 2)) { Ext.raise('publishState must either be called with no args, or with both name AND value passed'); } if (binding && !binding.syncing && !binding.isReadOnly()) { if (binding.calls || !(value == null || value === me.getInitialConfig()[property])) { binding.setValue(value); } } if (!(publishes = me.getPublishes())) { return; } if (!(vm = me.lookupViewModel())) { return; } if (!(path = me.viewModelKey)) { return; } state = state || (me.publishedState = {}); if (property) { if (!publishes[property]) { return; } if (!(value && value.constructor === Object) && !(value instanceof Array)) { if (state[property] === value) { return; } } path += '.'; path += property; } else { for (name in publishes) { ++count; state[name] = me.getConfig(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) { if (!binds) { return binds; } var me = this, viewModel = me.lookupViewModel(), twoWayable = me.getTwoWayBindable(), getBindTemplateScope = me._getBindTemplateScope, b, property, descriptor, destroy; me.$hasBinds = true; if (!currentBindings || typeof currentBindings === 'string') { currentBindings = {}; } if (!viewModel) { Ext.raise('Cannot use bind config without a viewModel'); } if (Ext.isString(binds)) { if (!me.defaultBindProperty) { Ext.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 && b.isBinding) { b.destroy(); b = null; destroy = true; } 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.raise('Cannot bind ' + property + ' on ' + me.$className + ' - missing a ' + b._config.names.set + ' method.'); } } if (destroy) { delete currentBindings[property]; } else { currentBindings[property] = b; } if (twoWayable && twoWayable[property]) { if (destroy) { me.clearBindableUpdater(property); } else if (!b.isReadOnly()) { me.addBindableUpdater(property); } } } return currentBindings; }, applyController: function(controller) { if (controller) { controller = Ext.Factory.controller(controller); controller.setView(this); } this.controller = controller; return controller; }, updatePublishes: function(all) { var me = this; if (me.lookupViewModel()) { for (var property in all) { me.addBindableUpdater(property); } } return all; }, 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) { return null; } if (!viewModel.isViewModel) { config = { parent: me.lookupViewModel(true), view: me }; 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(); }, clearBindableUpdater: function(property) { var me = this, configs = me.self.$config.configs, cfg = configs[property], updateName; if (cfg && me.hasOwnProperty(updateName = cfg.names.update)) { if (me[updateName].$bindableUpdater) { delete me[updateName]; } } }, destroyBindable: function() { var me = this, viewModel = me.getConfig('viewModel', true), session = me.getConfig('session', true), controller = me.getController(); if (viewModel && viewModel.isViewModel) { viewModel.destroy(); me.setViewModel(null); } if (session && session.isSession) { if (session.getAutoDestroy()) { session.destroy(); } me.setSession(null); } if (controller) { me.setController(null); controller.destroy(); } }, initBindable: function() { var me = this, controller = me.controller; me.initBindable = Ext.emptyFn; me.getBind(); me.getPublishes(); if (!me.viewModel) { me.getViewModel(); } if (controller) { controller.initBindings(); } if (me.reference) { me.publishState(); } }, isSyncing: function(name) { var bindings = this.getBind(), ret = false, binding; if (bindings) { binding = bindings[name]; if (binding) { ret = binding.syncing > 0; } } return ret; }, makeBindableUpdater: function(cfg) { var updateName = cfg.names.update, fn = function(newValue, oldValue) { var me = this, updater = me.self.prototype[updateName]; if (updater) { updater.call(me, newValue, oldValue); } me.publishState(cfg.name, me[cfg.getInternalName(me)]); }; fn.$bindableUpdater = true; return fn; }, notifyIf: function(skipThis) { var vm = this.lookupViewModel(skipThis); if (vm) { vm.notify(); } }, onBindNotify: function(value, oldValue, binding) { binding.syncing = (binding.syncing + 1) || 1; this[binding._config.names.set](value); --binding.syncing; }, removeBindings: function() { var me = this, bindings, key, binding; if (me.$hasBinds) { bindings = me.getBind(); if (bindings && typeof bindings !== 'string') { for (key in bindings) { binding = bindings[key]; binding.destroy(); binding._config = binding.getTemplateScope = null; } } } me.setBind(null); }, updateSession: function(session) { var state = this.getInherited(); if (session) { state.session = session; } else { delete state.session; } }, updateViewModel: function(viewModel, oldViewModel) { var me = this, state = me.getInherited(), controller = me.getController(); if (viewModel) { me.hasVM = true; state.viewModel = viewModel; viewModel.setView(me); if (controller) { controller.initViewModel(viewModel); } } else { delete state.viewModel; } me.viewModel = viewModel; } } }); Ext.define('Ext.mixin.ComponentDelegation', { extend: Ext.Mixin, mixinConfig: { id: 'componentDelegation' }, privates: { addDelegatedListener: function(eventName, fn, scope, options, order, caller, manager) { var me = this, delegatedEvents, event, priority; eventName = Ext.canonicalEventName(eventName); order = order || options.order; if (order) { priority = (options && options.priority); if (!priority) { options = options ? Ext.Object.chain(options) : {}; options.priority = me.$orderToPriority[order]; } } if (options.target) { Ext.raise("Cannot add '" + eventName + "' listener to component: '" + me.id + "' - 'delegate' and 'target' event options are incompatible."); } delegatedEvents = me.$delegatedEvents || (me.$delegatedEvents = {}); event = delegatedEvents[eventName] || (delegatedEvents[eventName] = new Ext.util.Event(me, eventName)); if (event.addListener(fn, scope, options, caller, manager)) { me.$hasDelegatedListeners._incr_(eventName); } }, clearDelegatedListeners: function() { var me = this, delegatedEvents = me.$delegatedEvents, eventName, event, listenerCount; if (delegatedEvents) { for (eventName in delegatedEvents) { event = delegatedEvents[eventName]; listenerCount = event.listeners.length; event.clearListeners(); me.$hasDelegatedListeners._decr_(eventName, listenerCount); delete delegatedEvents[eventName]; } } }, doFireDelegatedEvent: function(eventName, args) { var me = this, ret = true, owner, delegatedEvents, event; if (me.$hasDelegatedListeners[eventName]) { owner = me.getRefOwner(); while (owner) { delegatedEvents = owner.$delegatedEvents; if (delegatedEvents) { event = delegatedEvents[eventName]; if (event) { ret = event.fireDelegated(me, args); if (ret === false) { break; } } } owner = owner.getRefOwner(); } } return ret; }, removeDelegatedListener: function(eventName, fn, scope) { var me = this, delegatedEvents = me.$delegatedEvents, event; if (delegatedEvents) { event = delegatedEvents[eventName]; if (event && event.removeListener(fn, scope)) { me.$hasDelegatedListeners._decr_(eventName); if (event.listeners.length === 0) { delete delegatedEvents[eventName]; } } } }, destroyComponentDelegation: function() { if (this.clearPropertiesOnDestroy) { this.$delegatedEvents = null; } } }, onClassMixedIn: function(T) { function HasListeners() {} T.prototype.HasListeners = T.HasListeners = HasListeners; HasListeners.prototype = T.hasListeners = new Ext.mixin.ComponentDelegation.HasDelegatedListeners(); } }, function(ComponentDelegation) { function HasDelegatedListeners() {} ComponentDelegation.HasDelegatedListeners = HasDelegatedListeners; HasDelegatedListeners.prototype = ComponentDelegation.prototype.$hasDelegatedListeners = new Ext.mixin.Observable.HasListeners(); }); 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)); }, getCmp: function() { return this.cmp; }, setCmp: function(host) { this.cmp = host; }, init: Ext.emptyFn, destroy: function() { this.cmp = this.pluginConfig = null; this.callParent(); }, onClassExtended: function(cls, data, hooks) { var alias = data.alias, prototype = cls.prototype; if (alias && !data.ptype) { if (Ext.isArray(alias)) { alias = alias[0]; } 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); }, statics: { decode: function(plugins, typeProp, include) { if (plugins) { var type = Ext.typeOf(plugins), entry, key, obj, value; if (type === 'string') { obj = {}; obj[typeProp] = plugins; plugins = [ obj ]; } else if (plugins.isInstance) { plugins = [ plugins ]; } else if (type === 'object') { if (plugins[typeProp]) { plugins = [ plugins ]; } else { obj = include ? Ext.merge(Ext.clone(include), plugins) : plugins; plugins = []; for (key in obj) { if (!(value = obj[key])) { continue; } entry = { id: key }; entry[typeProp] = key; if (key === 'responsive') { entry.weight = -1000; } Ext.apply(entry, value); plugins.push(entry); } plugins.sort(Ext.weightSortFn); } } else if (type !== 'array') { Ext.raise('Invalid value for "plugins" config ("' + type + '"'); } else { plugins = plugins.slice(); } } return plugins; } } }); Ext.define('Ext.mixin.Pluggable', function(Pluggable) { return { config: { plugins: null }, addPlugin: function(plugin) { var me = this, plugins = me.getPlugins(); if (plugins) { plugin = me.createPlugin(plugin); plugin.init(me); plugins.push(plugin); } else { me.setPlugins(plugin); plugin = me.getPlugins()[0]; } return plugin; }, destroyPlugin: function(plugin) { return this.removePlugin(plugin, true); }, findPlugin: function(type) { var plugins = this.getPlugins(), n = plugins && plugins.length, i, plugin, ret; for (i = 0; i < n && !ret; i++) { plugin = plugins[i]; if (plugin.type === type || plugin.ptype === type) { ret = plugin; } } return ret || null; }, getPlugin: function(id) { var plugins = this.getPlugins(), n = plugins && plugins.length, i, plugin, ret; for (i = 0; i < n && !ret; i++) { plugin = plugins[i]; if (plugin.id === id || plugin.pluginId === id) { ret = plugin; } } return ret || null; }, removePlugin: function(plugin, destroy) { var plugins = this.getPlugins(), i = plugins && plugins.length || 0, p; while (i-- > 0) { p = plugins[i]; if (p === plugin || p.id === plugin) { plugins.splice(i, 1); if (destroy) { if (p.destroy) { p.destroy(); } } else if (p.detachCmp) { p.detachCmp(); if (p.setCmp) { p.setCmp(null); } } break; } p = null; } return p; }, privates: { statics: { idSeed: 0 }, activatePlugin: function(type) { var me = this, config = me.initialConfig, plugins = config && config.plugins, ret = null, i, include, p; if (plugins) { include = me.config.plugins; include = (include && typeof include === 'object') ? include : null; plugins = Ext.plugin.Abstract.decode(plugins, 'type', include); for (i = plugins.length; i-- > 0; ) { p = plugins[i]; if (p === type || p.type === type) { me.initialConfig = config = Ext.apply({}, config); config.plugins = plugins; plugins[i] = ret = me.createPlugin(p); break; } } } return ret; }, applyPlugins: function(plugins, oldPlugins) { var me = this, oldCount = oldPlugins && oldPlugins.length || 0, count, i, plugin; if (plugins) { plugins = Ext.plugin.Abstract.decode(plugins, 'type'); } for (i = 0; i < oldCount; ++i) { oldPlugins[i].$dead = true; } count = plugins && plugins.length || 0; for (i = 0; i < count; ++i) { plugins[i] = me.createPlugin(plugins[i]); } for (i = 0; i < count; ++i) { plugin = plugins[i]; if (plugin.$dead) { delete plugin.$dead; } else { plugin.init(me); } } for (i = 0; i < oldCount; ++i) { if ((plugin = oldPlugins[i]).$dead) { delete plugin.$dead; Ext.destroy(plugin); } } return plugins; }, createPlugin: function(config) { if (typeof config === 'string') { config = { type: config }; } var ret = config; if (!config.isInstance) { config.cmp = this; ret = Ext.factory(config, null, null, 'plugin'); delete config.cmp; } if (!ret.id) { ret.id = ++Pluggable.idSeed; } if (ret.setCmp) { ret.setCmp(this); } return ret; } } }; }); Ext.define('Ext.mixin.Keyboard', function(Keyboard) { return { extend: Ext.Mixin, mixinConfig: { id: 'keyboard' }, config: { keyMap: { $value: null, cached: true, merge: function(value, baseValue, cls, mixin) { if (value === null) { return value; } var ret = (baseValue && !cls.isInstance) ? Ext.Object.chain(baseValue) : {}, key, ucKey, v, vs; for (key in value) { if (key !== 'scope') { ucKey = key.toUpperCase(); if (!mixin || ret[ucKey] === undefined) { v = value[key]; if (v) { if (typeof v === 'string' || typeof v === 'function') { v = { handler: v }; } else { v = Ext.apply({ handler: v.fn }, v); } vs = v.scope || value.scope || 'self'; v.scope = (vs === 'controller') ? 'self.controller' : vs; } ret[ucKey] = v; } } } return ret; } }, keyMapEnabled: null }, keyMapTarget: 'el', applyKeyMap: function(keyMap, existingKeyMap) { var me = this, own = me.hasOwnProperty('config'); if (own && existingKeyMap && existingKeyMap.$owner !== me) { existingKeyMap = Ext.apply({}, existingKeyMap); } keyMap = keyMap ? Keyboard.combineKeyMaps(existingKeyMap, keyMap, own && me) : null; if (me._keyMapReady) { me.setKeyMapListener(keyMap && me.getKeyMapEnabled()); } return keyMap; }, initKeyMap: function() { var me = this, enabled = me.getKeyMapEnabled(); me._keyMapReady = true; if (enabled === null) { me.setKeyMapEnabled(true); } else { me.setKeyMapListener(enabled && me.getKeyMap()); } }, disableKeyMapGroup: function(group) { this.setKeyMapGroupEnabled(group, false); }, enableKeyMapGroup: function(group) { this.setKeyMapGroupEnabled(group, true); }, setKeyMapGroupEnabled: function(group, state) { var me = this, disabledGroups = me.disabledKeyMapGroups || (me.disabledKeyMapGroups = {}); disabledGroups[group] = !state; }, updateKeyMapEnabled: function(enabled) { this.setKeyMapListener(enabled && this._keyMapReady && this.getKeyMap()); }, privates: { _keyMapListenCount: 0, _keyMapReady: false, comparePriorities: function(lhs, rhs) { return (rhs.priority || 0) - (lhs.priority || 0); }, findKeyMapEntries: function(e) { var me = this, disabledGroups = me.disabledKeyMapGroups, keyMap = me.getKeyMap(), entries = keyMap && Keyboard.getKeyName(e), entry, len, i, result = []; entries = entries && keyMap[entries]; if (entries) { if (!entries.sorted) { Ext.Array.sort(entries, me.comparePriorities); entries.sorted = true; } len = entries.length; for (i = 0; i < len; i++) { entry = entries[i]; if (!disabledGroups || !disabledGroups[entry.group]) { if (Keyboard.matchEntry(entry, e)) { result.push(entry); } } } } return result; }, onKeyMapEvent: function(e) { var me = this, entries = me.getKeyMapEnabled() ? me.findKeyMapEntries(e) : null, len = entries && entries.length, i, entry, result; for (i = 0; i < len && result !== false; i++) { entry = entries[i]; result = Ext.callback(entry.handler, entry.scope, [ e, this ], 0, this); } return result; }, setKeyMapListener: function(enabled) { var me = this, listener = me._keyMapListener, eventSource; if (listener) { listener.destroy(); listener = null; } if (enabled) { ++me._keyMapListenCount; if (enabled) { eventSource = me[me.keyMapTarget]; if (typeof eventSource === 'function') { eventSource = eventSource.call(me); } listener = eventSource.on({ destroyable: true, scope: me, keydown: 'onKeyMapEvent', keypress: 'onKeyMapEvent' }); } } me._keyMapListener = listener || null; }, statics: { _charCodeRe: /^#([\d]+)$/, _keySpecRe: /^(?:(?:(\*)[\+\-])|(?:([a-z\+\-]*)[\+\-]))?(?:([a-z0-9_]+|[\+\-]|(?:#?\d+))(?:\:([a-z]+))?)$/i, _delimiterRe: /\-|\+/, _keyMapEvents: { charCode: 'keypress', keyCode: 'keydown' }, combineKeyMaps: function(existingKeyMap, keyMap, owner) { var defaultScope = keyMap.scope || 'controller', entry, key, mapping, existingMapping; for (key in keyMap) { if (key === 'scope') { continue; } if (!(mapping = keyMap[key])) { if (mapping === undefined) { Ext.raise('keyMap entry "' + key + '" is undefined'); } if (!existingKeyMap) { continue; } } else { if (typeof mapping === 'string' || typeof mapping === 'function') { mapping = { handler: mapping, scope: defaultScope }; } else if (mapping) { mapping = Ext.apply({ handler: mapping.fn, scope: defaultScope }, mapping); } existingKeyMap = existingKeyMap || {}; } if (Keyboard.parseEntry(key, entry = mapping || {})) { existingMapping = existingKeyMap[entry.name]; if (existingMapping) { if (owner && existingMapping.$owner !== owner) { existingKeyMap[entry.name] = existingMapping = existingMapping.slice(); existingMapping.$owner = owner; } existingMapping.push(mapping); existingMapping.sorted = false; } else { existingMapping = existingKeyMap[entry.name] = [ mapping ]; existingMapping.$owner = owner; existingMapping.sorted = true; } } else { Ext.raise('Invalid keyMap key specification "' + key + '"'); } } if (existingKeyMap && owner) { existingKeyMap.$owner = owner; } return existingKeyMap || null; }, getKeyName: function(event) { var keyCode; if (event.isEvent) { keyCode = event.keyCode || event.charCode; event = event.browserEvent; if (keyCode === 229 && 'code' in event) { if (Ext.String.startsWith(event.code, 'Key')) { return event.key.substr(3); } if (Ext.String.startsWith(event.code, 'Digit')) { return event.key.substr(5); } } } else { keyCode = event; } return Ext.event.Event.keyCodes[keyCode] || String.fromCharCode(keyCode); }, matchEntry: function(entry, e) { var ev = e.browserEvent, code; if (e.type !== entry.event) { return false; } if (!(code = entry.charCode)) { if (entry.keyCode !== e.keyCode || (!entry.ignoreModifiers && !entry.shiftKey !== !ev.shiftKey)) { return false; } } else if (e.getCharCode() !== code) { return false; } return entry.ignoreModifiers || (!entry.ctrlKey === !ev.ctrlKey && !entry.altKey === !ev.altKey && !entry.metaKey === !ev.metaKey && !entry.shiftKey === !ev.shiftKey); }, parseEntry: function(key, entry) { key = key.toUpperCase(); var me = this, Event = Ext.event.Event, keyFlags = Event.keyFlags, parts = me._keySpecRe.exec(key), type = 'keyCode', name, code, i, match, n; if (parts) { name = parts[3]; if (parts[4]) { entry.group = parts[4]; } if (!(entry.ignoreModifiers = !!parts[1]) && parts[2]) { parts = parts[2].split(me._delimiterRe); n = parts.length; for (i = 0; i < n; i++) { if (!keyFlags[parts[i]]) { return false; } entry[keyFlags[parts[i]]] = true; } } entry.name = name; if (isNaN(code = Event[name])) { if (!(match = me._charCodeRe.exec(name))) { if (name.length === 1) { code = name.charCodeAt(0); } } else { code = +match[1]; } if (code) { type = 'charCode'; } else { code = +name; } entry.name = Keyboard.getKeyName(code); } entry.event = entry.event || me._keyMapEvents[type]; return !isNaN(code) && (entry[type] = code); } } } } }; }); Ext.define('Ext.mixin.Focusable', { mixinId: 'focusable', $isFocusableEntity: true, focusable: false, hasFocus: false, containsFocus: false, focusCls: Ext.baseCSSPrefix + 'focused', focusEl: 'el', getFocusEl: function() { var focusEl = this.focusEl; return focusEl && focusEl.dom ? focusEl : null; }, getFocusClsEl: function() { return this.getFocusEl(); }, initFocusable: Ext.emptyFn, initFocusableEvents: function(force) { this.initFocusableElement(force); }, enableFocusable: Ext.emptyFn, disableFocusable: function() { var me = this; if (me.hasFocus) { me.revertFocus(); } me.removeFocusCls(); }, destroyFocusable: function() { var me = this; Ext.destroy(me.focusListeners); me.focusListeners = me.focusEnterEvent = me.focusTask = null; me.focusEl = me.ariaEl = null; }, isFocusable: function(deep) { var me = this, focusEl; if (!me.focusable && (!me.isContainer || !deep)) { return false; } focusEl = me.getFocusEl(); if (focusEl && me.canFocus()) { return focusEl && !focusEl.destroyed && focusEl.isFocusable(deep); } return false; }, isDestructing: function() { for (var c = this; c; c = c.getRefOwner()) { if (c.destroying || c.destroyed) { return true; } } return false; }, canFocus: function(skipVisibility, includeFocusTarget) { var me = this, ownerFC = me.ownerFocusableContainer, focusableIfDisabled = ownerFC && ownerFC.allowFocusingDisabledChildren, canFocus; canFocus = !me.destroyed && me.rendered && !me.isDestructing() && (me.isContainer || me.focusable) && (!me.isDisabled() || focusableIfDisabled) && (skipVisibility || me.isVisible(true)); return canFocus || (includeFocusTarget && !!me.findFocusTarget()); }, focus: function(selectText) { var me = this, focusTarget, focusElDom; if ((!me.focusable && !me.isContainer) || me.destroyed || me.destroying) { return false; } if (me.canFocus() && (focusTarget = me.getFocusEl())) { if (focusTarget.$isFocusableEntity) { return focusTarget.focus.apply(focusTarget, arguments); } focusElDom = focusTarget.dom; if (focusElDom) { focusTarget.focus(); if (selectText && (me.selectText || focusElDom.select)) { if (me.selectText) { if (Ext.isArray(selectText)) { me.selectText.apply(me, selectText); } else { me.selectText(); } } else { focusElDom.select(); } } } else if (focusTarget.focus) { focusTarget.focus(); } else { return false; } } else { focusTarget = me.findFocusTarget(); if (focusTarget && focusTarget != me) { return focusTarget.focus.apply(focusTarget, arguments); } else { return false; } } return true; }, onBlur: function(e) { var me = this, container = me.ownerFocusableContainer; me.hasFocus = false; if (me.beforeBlur && !me.beforeBlur.$emptyFn) { me.beforeBlur(e); } if (container) { container.beforeFocusableChildBlur(me, e); } me.removeFocusCls(e); if (me.hasListeners.blur) { me.fireEvent('blur', me, e); } if (me.postBlur && !me.postBlur.$emptyFn) { me.postBlur(e); } if (container) { container.afterFocusableChildBlur(me, e); } }, onFocus: function(e) { var me = this, container = me.ownerFocusableContainer; if (me.canFocus()) { if (me.beforeFocus && !me.beforeFocus.$emptyFn) { me.beforeFocus(e); } if (container) { container.beforeFocusableChildFocus(me, e); } me.addFocusCls(e); if (!me.hasFocus) { me.hasFocus = true; me.fireEvent('focus', me, e); } if (me.postFocus && !me.postFocus.$emptyFn) { me.postFocus(e); } if (container) { container.afterFocusableChildFocus(me, e); } } }, getTabIndex: function() { var me = this, el, index; if (!me.focusable) { return; } el = me.getFocusEl(); if (el) { if (el.$isFocusableEntity) { index = el.getTabIndex(); } else if (el.isElement && el.dom) { index = el.dom.getAttribute('tabIndex'); if (index !== null) { index -= 0; } } else { return; } } if (typeof index !== 'number') { index = me.tabIndex; } return index; }, setTabIndex: function(newTabIndex, focusEl) { var me = this, ownerFC = me.ownerFocusableContainer, focusableIfDisabled = ownerFC && ownerFC.allowFocusingDisabledChildren, el; if (!me.focusable && !me.forceTabIndex) { return; } me.tabIndex = newTabIndex; if (me.destroying || me.destroyed || (me.isDisabled() && !focusableIfDisabled)) { return; } el = focusEl || me.getFocusEl(); if (el) { if (el.$isFocusableEntity) { el.setTabIndex(newTabIndex); } else if (el.isElement && el.dom) { el.setTabIndex(newTabIndex); } } }, onFocusEnter: function(e) { var me = this; if (me.destroying || me.destroyed) { return; } me.focusEnterEvent = e; me.containsFocus = true; if (me.hasListeners.focusenter) { me.fireEvent('focusenter', me, e); } }, onFocusLeave: function(e) { var me = this; if (me.destroying || me.destroyed) { return; } me.focusEnterEvent = null; me.containsFocus = false; if (me.hasListeners.focusleave) { me.fireEvent('focusleave', me, e); } }, onFocusMove: Ext.emptyFn, privates: { forceTabIndex: false, revertFocus: function() { var me = this, focusEvent = me.focusEnterEvent, activeElement = Ext.Element.getActiveElement(), focusTarget, fromComponent, reverted; if (focusEvent && !me.preventRefocus && me.el.contains(activeElement)) { fromComponent = focusEvent.fromComponent; if (fromComponent && (fromComponent.destroyed || fromComponent.isDestructing())) { focusTarget = document.body; } else { focusTarget = focusEvent.relatedTarget; } if (focusTarget === document.body) { fromComponent = me.findFocusTarget(); if (fromComponent) { focusTarget = fromComponent.getFocusEl(); } } if (focusTarget && focusTarget.$isFocusableEntity) { if (!focusTarget.destroyed && focusTarget.isFocusable()) { focusTarget.focus(); } } else if (Ext.getDoc().contains(focusTarget) && Ext.fly(focusTarget).isFocusable()) { fromComponent = Ext.Component.from(focusTarget); if (fromComponent) { fromComponent.revertFocusTo(focusTarget); } else { focusTarget.focus(); } } else if (focusEvent.fromComponent && focusEvent.fromComponent.focus) { reverted = focusEvent.fromComponent.focus(); if (!reverted) { activeElement.blur(); } } } }, revertFocusTo: function(target) { target.focus(); }, findFocusTarget: function() { var me = this, parentAxis, candidate, len, i, focusTargets, focusIndex; if (me.preventRefocus) { return null; } for (parentAxis = [] , candidate = me.getRefOwner(); candidate; candidate = candidate.getRefOwner()) { if (!candidate.isDisabled()) { parentAxis.unshift(candidate); } } for (i = 0 , len = parentAxis.length; i < len; i++) { candidate = parentAxis[i]; if (candidate.destroying || !candidate.isVisible()) { parentAxis.length = i; break; } } for (i = parentAxis.length - 1; i >= 0; i--) { candidate = parentAxis[i]; focusTargets = Ext.ComponentQuery.query(':canfocus()', candidate); if (focusTargets.length) { focusIndex = Ext.Array.indexOf(focusTargets, Ext.ComponentManager.getActiveComponent()); return focusTargets[focusIndex + 1] || focusTargets[focusIndex - 1] || focusTargets[0]; } if (candidate.isFocusable && candidate.isFocusable()) { return candidate; } } }, initFocusableElement: function(force) { var me = this, tabIndex = me.getTabIndex(), focusEl = me.getFocusEl(); if (focusEl && !focusEl.$isFocusableEntity) { if (tabIndex != null && (force || me.canFocus(true))) { me.setTabIndex(tabIndex, focusEl); } if (!focusEl.dom.hasAttribute('data-componentid')) { focusEl.dom.setAttribute('data-componentid', me.id); } } }, addFocusCls: function(e) { var focusCls = this.focusCls, el; el = this.getFocusClsEl(); if (focusCls) { el = this.getFocusClsEl(e); if (el) { el.addCls(focusCls); } } }, removeFocusCls: function(e) { var focusCls = this.focusCls, el; if (focusCls) { el = this.getFocusClsEl(e); if (el) { el.removeCls(focusCls); } } }, handleFocusEvent: function(e) { var me = this, event; if (!me.focusable || me.destroying || me.destroyed) { return; } if (me.isFocusing(e)) { event = new Ext.event.Event(e.event); event.type = 'focus'; event.relatedTarget = e.fromElement; event.target = e.toElement; me.onFocus(event); } }, handleBlurEvent: function(e) { var me = this, event; if (!me.focusable || me.destroying || me.destroyed) { return; } if (e.toElement === document.body || me.isBlurring(e)) { event = new Ext.event.Event(e.event); event.type = 'blur'; event.target = e.fromElement; event.relatedTarget = e.toElement; me.onBlur(event); } }, isFocusing: function(e) { var focusEl = this.getFocusEl(); if (focusEl) { if (focusEl.isFocusing) { return focusEl.isFocusing(e); } else { return focusEl.dom === document.activeElement && e.toElement === focusEl.dom && e.fromElement !== e.toElement; } } return false; }, isBlurring: function(e) { var focusEl = this.getFocusEl(); if (focusEl) { if (focusEl.isFocusing) { return focusEl.isBlurring(e); } else { return focusEl.dom !== document.activeElement && e.fromElement === focusEl.dom && e.fromElement !== e.toElement; } } return false; }, blur: function() { var me = this, focusEl; if (!me.focusable || !me.canFocus()) { return; } focusEl = me.getFocusEl(); if (focusEl) { me.blurring = true; focusEl.blur(); delete me.blurring; } }, isTabbable: function() { var me = this, focusEl; if (me.focusable) { focusEl = me.getFocusEl(); if (focusEl && focusEl.isTabbable()) { return focusEl.isTabbable(); } } return false; }, disableTabbing: function() { var me = this, el = me.el, focusEl; if (me.destroying || me.destroyed) { return; } if (el) { el.saveTabbableState(); } focusEl = me.getFocusEl(); if (focusEl) { if (focusEl.$isFocusableEntity) { focusEl.disableTabbing(); } else if (focusEl.isElement && el && !el.contains(focusEl)) { focusEl.saveTabbableState(); } } }, enableTabbing: function(reset) { var me = this, el = me.el, focusEl; if (me.destroying || me.destroyed) { return; } focusEl = me.getFocusEl(); if (focusEl) { if (focusEl.$isFocusableEntity) { focusEl.enableTabbing(); } else if (focusEl.isElement && el && !el.contains(focusEl)) { focusEl.restoreTabbableState(); } } if (el) { el.restoreTabbableState({ reset: reset }); } } } }, function() { var keyboardModeCls = Ext.baseCSSPrefix + 'keyboard-mode', keyboardMode = false; Ext.enableKeyboardMode = Ext.isModern || !Ext.os.is.Desktop; Ext.setKeyboardMode = Ext.setKeyboardMode || function(keyboardMode) { Ext.keyboardMode = keyboardMode; Ext.getBody().toggleCls(keyboardModeCls, keyboardMode); }; Ext.isTouchMode = function() { return (Ext.now() - Ext.lastTouchTime) < 500; }; Ext.syncKeyboardMode = function(e) { if (!Ext.enableKeyboardMode) { return; } var type = e.type; if (type === 'pointermove') { keyboardMode = false; } else { keyboardMode = (type === 'keydown'); Ext.lastTouchTime = e.pointerType === 'touch' && Ext.now(); Ext.setKeyboardMode(keyboardMode); } }; function keyboardModeFocusHandler() { if (keyboardMode !== Ext.getBody().hasCls(keyboardModeCls)) { Ext.setKeyboardMode(keyboardMode); } } Ext.getEnableKeyboardMode = function() { return Ext.enableKeyboardMode; }; Ext.setEnableKeyboardMode = function(enable) { var listeners = { pointerdown: Ext.syncKeyboardMode, pointermove: Ext.syncKeyboardMode, keydown: Ext.syncKeyboardMode, capture: true, delegated: false }; Ext.enableKeyboardMode = !!enable; if (Ext.enableKeyboardMode) { Ext.getWin().on(listeners); Ext.on('focus', keyboardModeFocusHandler); } else { Ext.getWin().un(listeners); Ext.un('focus', keyboardModeFocusHandler); } }; Ext.onReady(function() { if (!Ext.enableKeyboardMode) { Ext.getBody().addCls(keyboardModeCls); } Ext.setEnableKeyboardMode(Ext.enableKeyboardMode); }); }); Ext.define('Ext.mixin.Accessible', { extend: Ext.Mixin, mixinConfig: { id: 'accessible' }, config: { ariaAttributes: { $value: null, lazy: true } }, ariaEl: 'el', privates: { getAriaLabelEl: function(reference) { var ids = [], refHolder, i, len, cmp, result; if (reference) { if (Ext.isFunction(reference)) { return reference.call(this); } else { if (!Ext.isArray(reference)) { reference = [ reference ]; } refHolder = this.lookupReferenceHolder(); if (refHolder) { for (i = 0 , len = reference.length; i < len; i++) { cmp = refHolder.lookupReference(reference[i]); if (cmp) { ids.push(cmp.ariaEl.id); } } } } } return ids.length ? ids.join(' ') : null; } } }); Ext.define('Ext.Widget', { extend: Ext.Evented, xtype: 'widget', alternateClassName: 'Ext.Gadget', mixins: [ Ext.mixin.Inheritable, Ext.mixin.Bindable, Ext.mixin.ComponentDelegation, Ext.mixin.Pluggable, Ext.mixin.Keyboard, Ext.mixin.Factoryable, Ext.mixin.Focusable, Ext.mixin.Accessible ], isWidget: true, factoryConfig: { creator: null, defaultProperty: 'xtype', defaultType: 'component', typeProperty: 'xtype' }, element: { reference: 'element' }, observableType: 'component', cachedConfig: { cls: null, style: null, border: null, touchAction: null, eventHandlers: { focus: 'handleFocusEvent', blur: 'handleBlurEvent' } }, name: null, config: { renderTo: null, ui: null, userCls: null, ripple: null, hideMode: null, instanceCls: null }, eventedConfig: { width: null, height: null, hidden: null, disabled: null }, template: [], baseCls: null, classCls: null, classClsRoot: true, classClsList: [], clearPropertiesOnDestroy: 'async', focusEl: 'element', ariaEl: 'element', spaceRe: /\s+/, noBorderCls: Ext.baseCSSPrefix + 'noborder-trbl', borderedCls: Ext.baseCSSPrefix + 'bordered', disabledCls: Ext.baseCSSPrefix + 'disabled', heightedCls: Ext.baseCSSPrefix + 'heighted', widthedCls: Ext.baseCSSPrefix + 'widthed', constructor: function(config) { var me = this, baseCls = me.baseCls, renderTo = config && config.renderTo, controller; me.$iid = ++Ext.$nextIid; if (baseCls == null || baseCls === true) { me.baseCls = me.classCls || Ext.baseCSSPrefix + me.xtype; } if (config && ('baseCls' in config)) { Ext.raise('baseCls cannot be used as an instance config. It must be specified at class definition time.'); } if ((config && config.controller) || me.config.controller) { me.referenceHolder = true; } me.initId(config); me.initElement(); if (renderTo) { config = Ext.apply({}, config); delete config.renderTo; } me.mixins.observable.constructor.call(me, config); if (me.focusable) { me.initFocusableEvents(true); } if (renderTo) { me.setRenderTo(renderTo); } me.syncUiCls(); Ext.ComponentManager.register(me); controller = me.getController(); if (controller) { controller.init(me); } }, afterCachedConfig: function() { var me = this, prototype = me.self.prototype, referenceList = me.referenceList, renderElement = me.renderElement, renderTemplate, element, i, ln, reference, elements; prototype.renderTemplate = renderTemplate = document.createDocumentFragment(); renderTemplate.appendChild(renderElement.clone(true, 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'); } }, applyHidden: function(hidden) { return !!hidden; }, applyDisabled: function(disabled) { return !!disabled; }, updateDisabled: function(disabled) { var me = this, container = me.ownerFocusableContainer; if (container) { if (disabled) { if (!container.beforeFocusableChildDisable.$nullFn) { container.beforeFocusableChildDisable(me); } } else { if (!container.beforeFocusableChildEnable.$nullFn) { container.beforeFocusableChildEnable(me); } } } me.element.toggleCls(me.disabledCls, disabled); if (me.focusable) { if (disabled) { me.disableFocusable(); } else { me.enableFocusable(); } } if (container) { if (disabled) { if (!container.onFocusableChildDisable.$nullFn) { container.onFocusableChildDisable(me); } } else { if (!container.onFocusableChildEnable.$nullFn) { container.onFocusableChildEnable(me); } } } }, disable: function() { this.setDisabled(true); }, enable: function() { this.setDisabled(false); }, isDisabled: function() { return this.getDisabled(); }, isEnabled: function() { return !this.getDisabled(); }, applyTouchAction: function(touchAction, oldTouchAction) { if (oldTouchAction != null) { touchAction = Ext.merge({}, oldTouchAction, touchAction); } return touchAction; }, applyWidth: function(width) { return this.filterLengthValue(width); }, applyHeight: function(height) { return this.filterLengthValue(height); }, updateBorder: function(border) { var me = this; border = border || border === null; me.toggleCls(me.noBorderCls, !border); me.toggleCls(me.borderedCls, !!border); }, clearListeners: function() { var me = this; me.mixins.observable.clearListeners.call(me); me.mixins.componentDelegation.clearDelegatedListeners.call(me); }, destroy: function() { var me = this; me.isDestroying = me.destroying = true; me.doDestroy(); me.clearListeners(); me.isDestroying = me.destroying = false; me.mixins.componentDelegation.destroyComponentDelegation.call(me); me.callParent(); }, doDestroy: function() { var me = this, referenceList = me.referenceList, container = me.ownerFocusableContainer, i, ln, reference; me.ownerCmp = null; if (container && !container.onFocusableChildDestroy.$nullFn) { container.onFocusableChildDestroy(me); } for (i = 0 , ln = referenceList.length; i < ln; i++) { reference = referenceList[i]; if (me.hasOwnProperty(reference)) { me[reference].destroy(); me[reference] = null; } } me.destroyBindable(); Ext.ComponentManager.unregister(me); }, doFireEvent: function(eventName, args, bubbles) { var me = this, ret; ret = me.mixins.observable.doFireEvent.call(me, eventName, args, bubbles); if (ret !== false && !me.destroyed) { ret = me.mixins.componentDelegation.doFireDelegatedEvent.call(me, eventName, args); } return ret; }, getBubbleTarget: function() { return this.getRefOwner(); }, getElementConfig: function() { var me = this, el = me.element; if (!('children' in el)) { el = Ext.apply({ children: me.getTemplate() }, el); } return el; }, getSize: function() { return this.el.getSize(); }, getTemplate: function() { return Ext.clone(this.template); }, getClassCls: function() { var proto = this.self.prototype, prototype = proto, classes, classCls, i, ln; while (prototype) { classCls = prototype.hasOwnProperty('classCls') ? prototype.classCls : null; if (classCls) { if (classCls instanceof Array) { for (i = 0 , ln = classCls.length; i < ln; i++) { (classes || (classes = [])).push(classCls[i]); } } else { (classes || (classes = [])).push(classCls); } } if (prototype.classClsRoot && prototype.hasOwnProperty('classClsRoot')) { break; } prototype = prototype.superclass; } if (classes) { proto.classClsList = classes; } return classes; }, hide: function() { this.setHidden(true); }, initElement: function() { var me = this, prototype = me.self.prototype, id = me.getId(), referenceList = me.referenceList = me.referenceList = [], isFirstInstance = !prototype.hasOwnProperty('renderTemplate'), uiReferences = prototype.hasOwnProperty('uiReferences') ? prototype.uiReferences : (prototype.uiReferences = { element: '' }), renderTemplate, renderElement, renderConfig, element, referenceNodes, i, ln, referenceNode, reference, classCls, uiCls, baseCls, referenceElement; if (isFirstInstance) { renderTemplate = document.createDocumentFragment(); renderConfig = me.processElementConfig.call(prototype); renderElement = Ext.Element.create(renderConfig, true); renderTemplate.appendChild(renderElement); referenceNodes = renderTemplate.querySelectorAll('[uiCls]'); for (i = 0 , ln = referenceNodes.length; i < ln; i++) { referenceNode = referenceNodes[i]; reference = referenceNode.getAttribute('reference'); uiCls = referenceNode.getAttribute('uiCls'); if (!reference) { Ext.raise('Cannot render element with uiCls="' + uiCls + '". uiCls is only allowed on elements that have a reference name.'); } uiReferences[reference] = uiCls; referenceNode.removeAttribute('uiCls'); } } else { renderTemplate = me.renderTemplate.cloneNode(true); renderElement = renderTemplate.firstChild; } referenceNodes = renderTemplate.querySelectorAll('[reference]'); for (i = 0 , ln = referenceNodes.length; i < ln; i++) { referenceNode = referenceNodes[i]; reference = referenceNode.getAttribute('reference'); if (!isFirstInstance) { referenceNode.removeAttribute('reference'); } if (reference === 'element') { if (element) { Ext.raise("Duplicate 'element' reference detected in '" + me.$className + "' template."); } referenceNode.id = id; element = me.el = me.addElementReference(reference, referenceNode); element.dom.setAttribute('data-componentid', id); if (isFirstInstance) { classCls = me.getClassCls(); if (classCls) { element.addCls(classCls); } baseCls = me.baseCls; if (baseCls && (baseCls !== me.classCls)) { element.addCls(baseCls); } } } else { uiCls = uiReferences[reference]; if (uiCls && isFirstInstance) { referenceElement = me.addElementReference(reference, referenceNode); me.initUiReference(reference, uiCls, false); } else { me.addElementReferenceOnDemand(reference, referenceNode); } } if (reference === me.focusEl) { me.addElementReference('focusEl', referenceNode); } if (reference === me.ariaEl) { me.addElementReferenceOnDemand('ariaEl', referenceNode); } referenceList.push(reference); } if (!element) { Ext.raise("No 'element' reference found in '" + me.$className + "' template."); } if (renderElement === element.dom) { me.renderElement = element; } else { me.addElementReferenceOnDemand('renderElement', renderElement); } renderElement.setAttribute(me.dataXid, me.$iid); }, dataXid: 'data-' + Ext.baseCSSPrefix.substr(0, Ext.baseCSSPrefix.length - 1) + 'id', is: function(selector) { return Ext.ComponentQuery.is(this, selector); }, isHidden: function(deep) { var hidden = !!this.getHidden(), owner; if (!hidden && deep) { owner = this.getRefOwner(); while (owner && owner !== deep && !hidden) { hidden = !!owner.getHidden(); owner = owner.getRefOwner(); } } return hidden; }, isVisible: function(deep) { return this.rendered && !this.destroyed && !this.isHidden(deep); }, isXType: function(xtype, shallow) { return shallow ? (Ext.Array.indexOf(this.xtypes, xtype) !== -1) : !!this.xtypesMap[xtype]; }, lookupTpl: function(name) { return Ext.XTemplate.getTpl(this, name); }, owns: function(element) { var result = false, cmp; if (element.isEvent) { element = element.target; } else if (element.isElement) { element = element.dom; } cmp = Ext.Component.from(element); if (cmp) { result = (cmp === this) || (!!cmp.up(this)); } return result; }, render: function(container, insertBeforeElement) { if (container && container.isWidget) { container = container.el; } var dom = this.renderElement.dom, containerDom = Ext.getDom(container), insertBeforeChildDom; if (Ext.isNumber(insertBeforeChildDom)) { insertBeforeElement = containerDom.childNodes[insertBeforeElement]; } insertBeforeChildDom = Ext.getDom(insertBeforeElement); if (containerDom) { if (insertBeforeChildDom) { containerDom.insertBefore(dom, insertBeforeChildDom); } else { containerDom.appendChild(dom); } this.setRendered(Ext.getBody().contains(dom), true); } }, toggleCls: function(className, state) { this.element.toggleCls(className, state); return this; }, resolveListenerScope: function(defaultScope, skipThis) { return this.mixins.inheritable.resolveListenerScope.call(this, defaultScope, skipThis); }, setSize: function(width, height) { if (width && typeof width === 'object') { return this.setSize(width.width, width.height); } if (width !== undefined) { this.setWidth(width); } if (height !== undefined) { this.setHeight(height); } }, show: function() { this.setHidden(false); }, addCls: function(cls, prefix, suffix) { if (!this.destroyed) { this.el.replaceCls(null, cls, prefix, suffix); } }, applyCls: function(cls) { return cls && Ext.dom.Element.splitCls(cls); }, applyUi: function(ui) { return this.parseUi(ui, true); }, removeCls: function(cls, prefix, suffix) { if (!this.destroyed) { this.el.replaceCls(cls, null, prefix, suffix); } }, replaceCls: function(oldCls, newCls, prefix, suffix) { if (!this.destroyed) { this.el.replaceCls(oldCls, newCls, prefix, suffix); } }, hasCls: function(className) { return this.el.hasCls(className); }, updateCls: function(newCls, oldCls) { this.element.replaceCls(oldCls, newCls); }, updateHidden: function(hidden) { var me = this, element = me.renderElement, container = me.ownerFocusableContainer; if (container) { if (hidden) { if (!container.beforeFocusableChildHide.$nullFn) { container.beforeFocusableChildHide(me); } } else { if (!container.beforeFocusableChildShow.$nullFn) { container.beforeFocusableChildShow(me); } } } else if (hidden) { me.revertFocus(); } if (element && !element.destroyed) { if (hidden) { element.hide(); } else { element.show(); } } if (me.focusableContainer && me.activateFocusableContainer) { me.activateFocusableContainer(!hidden); } if (container) { if (hidden) { if (!container.onFocusableChildHide.$nullFn) { container.onFocusableChildHide(me); } } else { if (!container.onFocusableChildShow.$nullFn) { container.onFocusableChildShow(me); } } } }, updateRipple: function(ripple) { var me = this, el = me.el; if (el) { el.un('touchstart', 'onRippleStart', me); el.un('touchend', 'onRippleStart', me); el.destroyAllRipples(); if (ripple.release) { el.on('touchend', 'onRippleStart', me); } else { el.on('touchstart', 'onRippleStart', me); } } }, shouldRipple: function(e) { var me = this, disabled = me.getDisabled && me.getDisabled(), el = me.el, ripple = !disabled && me.getRipple(), target; if (ripple && e) { target = e.getTarget(me.noRippleSelector); if (target) { if ((el.dom === target) || el.contains(target)) { ripple = null; } } } return ripple; }, onRippleStart: function(e) { var ripple = this.shouldRipple(e); if (e.button === 0 && ripple) { this.el.ripple(e, ripple); } }, applyStyle: function(style, oldStyle) { if (oldStyle && style === oldStyle && Ext.isObject(oldStyle)) { style = Ext.apply({}, style); } this.element.applyStyles(style); return null; }, getStyle: function() { Ext.Error.raise("'style' is a write-only config. To query element styles use the Ext.dom.Element API."); }, updateRenderTo: function(newContainer) { this.render(newContainer); }, updateTouchAction: function(touchAction) { var name, childEl, value, hasRootActions; for (name in touchAction) { childEl = this[name]; value = touchAction[name]; if (childEl && childEl.isElement) { childEl.setTouchAction(value); } else { hasRootActions = true; } } if (hasRootActions) { this.el.setTouchAction(touchAction); } }, updateUi: function() { if (!this.isConfiguring) { this.syncUiCls(); } }, updateWidth: function(width) { var el = this.el; el.setWidth(width); el.toggleCls(this.widthedCls, width != null && width !== 'auto'); }, updateHeight: function(height) { var el = this.el; el.setHeight(height); el.toggleCls(this.heightedCls, height != null && height !== 'auto'); }, isWidthed: function() { var width = this.getWidth(); return width != null && width !== 'auto'; }, isHeighted: function() { var height = this.getHeight(); return height != null && height !== 'auto'; }, 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()) { if (result.destroyed) { return null; } steps++; if (selector.isComponent || selector.isWidget) { 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; }, updateLayout: Ext.emptyFn, updateInstanceCls: function(instanceCls, oldInstanceCls) { var me = this, el = me.el, classClsList = me.classClsList, Array = Ext.Array, uiReferences = me.uiReferences, referenceName, referenceElement, i, ln, cls, uiCls; if (oldInstanceCls) { el.removeCls(oldInstanceCls); oldInstanceCls = Array.from(oldInstanceCls); for (i = 0 , ln = oldInstanceCls.length; i < ln; i++) { cls = oldInstanceCls[i]; Array.remove(classClsList, cls); for (referenceName in uiReferences) { referenceElement = me[referenceName]; uiCls = uiReferences[referenceName]; referenceElement.removeCls(cls + '-' + uiCls); } } } if (instanceCls) { el.addCls(instanceCls); instanceCls = Array.from(instanceCls); me.classClsList = classClsList.concat(instanceCls); for (i = 0 , ln = instanceCls.length; i < ln; i++) { cls = instanceCls[i]; for (referenceName in uiReferences) { referenceElement = me[referenceName]; uiCls = uiReferences[referenceName]; referenceElement.addCls(cls + '-' + uiCls); } } } if (!me.isConfiguring) { me.syncUiCls(); } }, getBaseCls: function() { return this.baseCls; }, setBaseCls: function() { Ext.raise('baseCls cannot be reconfigured. It must be specified at class definition time.'); }, onClassExtended: function(Class, members) { if (members.config && members.config.baseCls) { Ext.raise('baseCls must be declared directly on the class body. Please move it outside of the config block.'); } }, privates: { _hideModes: { clip: 'CLIP', display: 'DISPLAY', offsets: 'OFFSETS', opacity: 'OPACITY', visibility: 'VISIBILITY' }, noRippleSelector: '.' + Ext.baseCSSPrefix + 'no-ripple', addElementReferenceOnDemand: function(name, domNode) { if (this._elementListeners[name]) { this.addElementReference(name, domNode); } else { Ext.Object.defineProperty(this, name, { get: function() { if (this.destroyed) { return; } 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); for (eventName in listeners) { listener = listeners[eventName]; if (typeof listener === 'object') { listener.scope = me; } } listeners.scope = me; referenceEl.on(listeners); } return referenceEl; }, detachFromBody: function() { Ext.getDetachedBody().appendChild(this.element, true); this.isDetached = true; }, reattachToBody: function() { var detachedBody; if (this.isDetached) { detachedBody = Ext.getDetachedBody(); if (detachedBody.contains(this.element)) { Ext.getBody().appendChild(this.element, true); } } this.isDetached = false; }, doAddListener: function(name, fn, scope, options, order, caller, manager) { var me = this, elementName = options && options.element, delegate = options && options.delegate, listeners, eventOptions, option; if (elementName) { if (Ext.Array.indexOf(me.referenceList, elementName) === -1) { Ext.Logger.error("Adding event listener with an invalid element reference of '" + elementName + "' for this component. Available values are: '" + me.referenceList.join("', '") + "'", me); } listeners = {}; listeners[name] = fn; if (scope) { listeners.scope = scope; } eventOptions = Ext.Element.prototype.$eventOptions; for (option in options) { if (eventOptions[option]) { listeners[option] = options[option]; } } me.mon(me[elementName], listeners); return; } else if (delegate) { me.mixins.componentDelegation.addDelegatedListener.call(me, name, fn, scope, options, order, caller, manager); return; } me.callParent([ name, fn, scope, options, order, caller, manager ]); }, doRemoveListener: function(eventName, fn, scope) { var me = this; me.mixins.observable.doRemoveListener.call(me, eventName, fn, scope); me.mixins.componentDelegation.removeDelegatedListener.call(me, eventName, fn, scope); }, filterLengthValue: function(value) { if (!value && value !== 0) { return null; } return value; }, 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(); } }, measure: function(dimension) { return this.element.measure(dimension); }, 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; }, parseUi: function(ui, asString) { ui = Ext.String.splitWords(ui); if (asString) { ui = ui.join(' '); } return ui; }, addUi: function(ui) { this.setUi(this.doAddUi(ui, this.getUi())); }, doAddUi: function(ui, oldUi) { var me = this, newUi = null, i, u, len; if (ui) { ui = me.parseUi(ui); len = ui.length; oldUi = me.parseUi(oldUi); for (i = 0; i < len; i++) { u = ui[i]; if (Ext.Array.indexOf(oldUi, u) === -1) { oldUi.push(u); } } newUi = oldUi.join(' '); } return newUi; }, removeUi: function(ui) { this.setUi(this.doRemoveUi(ui, this.getUi())); }, doRemoveUi: function(ui, oldUi) { var me = this, newUi = null, i, u, index, len; if (ui) { ui = me.parseUi(ui); len = ui.length; oldUi = me.parseUi(oldUi); for (i = 0; i < len; i++) { u = ui[i]; index = Ext.Array.indexOf(oldUi, u); if (index !== -1) { oldUi.splice(index, 1); } } newUi = oldUi.join(' '); } return newUi; }, initUiReference: function(referenceName, uiCls, isInstance) { var me = this, referenceElement = me[referenceName], baseCls = me.baseCls, classClsList = me.classClsList, cls = [], i, n; isInstance = (isInstance !== false); if (isInstance) { if (!me.hasOwnProperty('uiReferences')) { me.uiReferences = Ext.clone(me.uiReferences); } me.uiReferences[referenceName] = uiCls; } uiCls = '-' + uiCls; if (baseCls && (baseCls !== me.classCls)) { cls.push(baseCls + uiCls); } if (classClsList) { for (i = 0 , n = classClsList.length; i < n; i++) { cls.push(classClsList[i] + uiCls); } } referenceElement.addCls(cls); if (isInstance && !me.isConfiguring) { me.syncUiCls(); } }, syncUiCls: function(refs) { var me = this, ui = me.getUi(), currentUiCls = me.currentUiCls || (me.currentUiCls = {}), baseCls = me.baseCls, uiReferences = refs || me.uiReferences, classClsList = me.classClsList, classClsListLen = classClsList ? classClsList.length : 0, uiCls, uiLen, refName, refEl, cls, suffix, uiSuffix, i, j; if (ui) { ui = me.parseUi(ui); uiLen = ui.length; } for (refName in uiReferences) { refEl = me[refName]; uiCls = []; if (refEl) { cls = currentUiCls[refName]; if (cls) { refEl.removeCls(cls); } if (ui) { suffix = uiReferences[refName]; suffix = suffix ? ('-' + suffix) : ''; for (i = 0; i < uiLen; i++) { uiSuffix = '-' + ui[i] + suffix; if (baseCls && (baseCls !== me.classCls)) { uiCls.push(baseCls + uiSuffix); } if (classClsList) { for (j = 0; j < classClsListLen; j++) { uiCls.push(classClsList[j] + uiSuffix); } } } refEl.addCls(uiCls); currentUiCls[refName] = uiCls; } } } }, applyHideMode: function(mode) { return mode || 'display'; }, updateHideMode: function(mode) { var me = this, el = me.el, shouldToggle = me.getHidden(); if (!me._hideModes[mode]) { Ext.raise('Invalid hideMode: "' + mode + '" (must be one of: "' + Object.keys(me._hideModes).join('", "') + '")'); } if (shouldToggle) { el.show(); } me.renderElement.setVisibilityMode(Ext.Element[me._hideModes[mode]]); if (shouldToggle) { el.hide(); } }, updateUserCls: function(newCls, oldCls) { this.element.replaceCls(oldCls, newCls); } } }, function(Widget) { var prototype = Widget.prototype; (prototype.$elementEventOptions = Ext.Object.chain(Ext.Element.prototype.$eventOptions)).element = 1; (prototype.$eventOptions = Ext.Object.chain(prototype.$eventOptions)).delegate = 1; Ext.updateWidget = Ext.Factory.widget.update; }); Ext.define('Ext.mixin.Traversable', { extend: Ext.Mixin, mixinConfig: { id: 'traversable' }, setParent: function(parent) { this.parent = parent; return this; }, hasParent: function() { return Boolean(this.getParent()); }, is: function() { return true; }, getParent: function() { return this.parent || this.$initParent; }, 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; }, previousNode: function(selector, includeSelf) { var node = this, parent = node.getRefOwner(), result, it, i, sibling; if (includeSelf && node.is(selector)) { return node; } if (parent) { for (it = parent.items.items , i = Ext.Array.indexOf(it, node) - 1; i > -1; i--) { sibling = it[i]; if (sibling.query) { result = sibling.query(selector); result = result[result.length - 1]; if (result) { return result; } } if (!selector || sibling.is(selector)) { return sibling; } } return parent.previousNode(selector, true); } return null; }, previousSibling: function(selector) { var parent = this.getRefOwner(), it, idx, sibling; if (parent) { it = parent.items; idx = it.indexOf(this); if (idx !== -1) { if (selector) { for (--idx; idx >= 0; idx--) { if ((sibling = it.getAt(idx)).is(selector)) { return sibling; } } } else { if (idx) { return it.getAt(--idx); } } } } return null; }, nextNode: function(selector, includeSelf) { var node = this, parent = node.getRefOwner(), result, it, len, i, sibling; if (includeSelf && node.is(selector)) { return node; } if (parent) { for (it = parent.items.items , i = Ext.Array.indexOf(it, node) + 1 , len = it.length; i < len; i++) { sibling = it[i]; if (!selector || sibling.is(selector)) { return sibling; } if (sibling.down) { result = sibling.down(selector); if (result) { return result; } } } return parent.nextNode(selector); } return null; }, nextSibling: function(selector) { var parent = this.getRefOwner(), it, last, idx, sibling; if (parent) { it = parent.items; idx = it.indexOf(this) + 1; if (idx) { if (selector) { for (last = it.getCount(); idx < last; idx++) { if ((sibling = it.getAt(idx)).is(selector)) { return sibling; } } } else { if (idx < it.getCount()) { return it.getAt(idx); } } } } return null; } }); 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.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.util.translatable.Abstract', { extend: Ext.Evented, mixins: [ Ext.mixin.Factoryable ], factoryConfig: { type: 'translatable', defaultType: 'csstransform' }, config: { easing: null, easingX: { duration: 300 }, easingY: { duration: 300 } }, x: 0, y: 0, activeEasingX: null, activeEasingY: null, isAnimating: false, isTranslatable: true, constructor: function(config) { this.callParent([ 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: function(x, y) { if (this.hasListeners.translate) { this.fireEvent('translate', this, x, y); } }, 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) { var me = this; me.activeEasingX = easingX; me.activeEasingY = easingY; me.isAnimating = true; if (me.ownerCmp) { me.ownerCmp.isTranslating = true; } me.lastX = null; me.lastY = null; Ext.AnimationQueue.start(me.doAnimationFrame, me); me.fireEvent('animationstart', me, me.x, me.y); return me; }, translateAnimated: function(x, y, animation) { var me = this, now, easing, easingX, easingY; if (!Ext.isObject(animation)) { animation = {}; } if (me.isAnimating) { me.stopAnimation(); } me.callback = animation.callback; me.callbackScope = animation.scope; 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; if (me.ownerCmp) { me.ownerCmp.isTranslating = 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); }, resolveListenerScope: function() { var ownerCmp = this.ownerCmp, a = arguments; if (ownerCmp) { return ownerCmp.resolveListenerScope.apply(ownerCmp, a); } return this.callParent(a); }, destroy: function() { var me = this; me.destroying = true; if (me.isAnimating) { me.stopAnimation(); } me.callParent(); me.destroying = false; me.destroyed = true; } }); Ext.define('Ext.util.Format', function() { var me; return { singleton: true, defaultDateFormat: 'm/d/Y', thousandSeparator: ',', decimalSeparator: '.', currencyPrecision: 2, currencySign: '$', currencySpacer: '', 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; }, nbsp: function(value, strict) { strict = strict !== false; if (strict ? value === '' || value == null : !value) { value = '\xa0'; } return value; }, 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(value) { return me.currency(value, '$', 2); }, currency: function(value, currencySign, decimals, end, currencySpacer) { var negativeSign = '', format = ",0", i = 0; value = value - 0; if (value < 0) { value = -value; negativeSign = '-'; } decimals = Ext.isDefined(decimals) ? decimals : me.currencyPrecision; format += (decimals > 0 ? '.' : ''); for (; i < decimals; i++) { format += '0'; } value = me.number(value, format); if (currencySpacer == null) { currencySpacer = me.currencySpacer; } if ((end || me.currencyAtEnd) === true) { return Ext.String.format("{0}{1}{2}{3}", negativeSign, value, currencySpacer, currencySign || me.currencySign); } else { return Ext.String.format("{0}{1}{2}{3}", negativeSign, currencySign || me.currencySign, currencySpacer, value); } }, date: function(value, format) { if (!value) { return ""; } if (!Ext.isDate(value)) { value = new Date(Date.parse(value)); } return Ext.Date.dateFormat(value, 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; }, lessThanElse: function(value, threshold, below, above, equal) { var v = Ext.Number.from(value, 0), t = Ext.Number.from(threshold, 0), missing = !Ext.isDefined(equal); return v < t ? below : (v > t ? above : (missing ? above : equal)); }, sign: function(value, negative, positive, zero) { if (zero === undefined) { zero = positive; } return me.lessThanElse(value, 0, negative, positive, zero); }, stripTags: function(value) { return !value ? value : String(value).replace(me.stripTagsRe, ""); }, stripScripts: function(value) { return !value ? value : String(value).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.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 }; }, resource: function(url, prefix) { prefix = prefix || ''; return Ext.resolveResource(prefix + url); }, uri: function(value) { return encodeURI(value); }, uriCmp: function(value) { return encodeURIComponent(value); }, wordBreakRe: /[\W\s]+/, word: function(value, index, sep) { var re = sep ? (typeof sep === 'string' ? new RegExp(sep) : sep) : me.wordBreakRe, parts = (value || '').split(re); return parts[index || 0] || ''; } }; }); Ext.define('Ext.Template', { 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 = [], length = args.length, i, 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.String.formatEncode = function() { return Ext.String.htmlEncode(Ext.String.format.apply(this, arguments)); }; }); Ext.define('Ext.util.XTemplateParser', { 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; me.definitions = me.body = me.switches = 0; 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, isXTemplate: true, emptyObj: {}, fn: null, strict: false, apply: function(values, parent, xindex, xcount) { var buffer = this.applyOut(values, [], parent, xindex, xcount); return buffer.length === 1 ? buffer[0] : buffer.join(''); }, applyOut: function(values, out, parent, xindex, xcount) { 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); } xindex = xindex || 1; xcount = xcount || 1; if (me.strict) { me.fn(out, values, parent || me.emptyObj, xindex, xcount); } else { try { me.fn(out, values, parent || me.emptyObj, xindex, xcount); } catch (e) { Ext.log.warn('XTemplate evaluation exception: ' + e.message); } } return out; }, compile: function() { return this; }, statics: { get: function(config, source, defaultTpl) { var ret = config; if (config == null) { if (source && defaultTpl) { ret = this.getTpl(source, defaultTpl); } } else if ((config || config === '') && !config.isTemplate) { ret = new this(config); } return ret; }, getTpl: function(instance, name) { var tpl = instance[name], owner; if (tpl) { if (!tpl.isTemplate) { tpl = Ext.XTemplate.get(tpl); } if (!tpl.owner) { 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.util.translatable.Dom', { extend: Ext.util.translatable.Abstract, alias: 'translatable.dom', config: { element: null }, applyElement: function(element) { if (!element) { return; } return Ext.get(element); }, updateElement: function() { this.refresh(); } }); Ext.define('Ext.util.translatable.CssPosition', { extend: Ext.util.translatable.Dom, alias: 'translatable.cssposition', 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'; } this.callParent([ x, y ]); }, syncPosition: function() { var domStyle = this.getElement().dom.style; return [ this.x = parseFloat(domStyle.left), this.y = parseFloat(domStyle.top) ]; }, destroy: function() { var domStyle = this.getElement().dom.style; domStyle.left = null; domStyle.top = null; this.callParent(); } }); Ext.define('Ext.util.translatable.CssTransform', { extend: Ext.util.translatable.Dom, alias: 'translatable.csstransform', isCssTransform: true, posRegex: /(\d+)px[^\d]*(\d+)px/, doTranslate: function(x, y) { var me = this, element = me.getElement(); if (!me.destroyed && !element.destroyed) { element.translate(x, y); } me.callParent([ x, y ]); }, syncPosition: function() { var pos = this.posRegex.exec(this.getElement().dom.style.tranform); if (pos) { this.x = parseFloat(pos[1]); this.y = parseFloat(pos[2]); } return [ this.x, this.y ]; }, destroy: function() { var element = this.getElement(); if (element && !element.destroyed) { element.dom.style.webkitTransform = null; } this.callParent(); } }); 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(stylesheet) { var styleEl = (typeof stylesheet === 'string') ? doc.getElementById(stylesheet) : stylesheet.ownerNode; if (styleEl) { styleEl.parentNode.removeChild(styleEl); } }, 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.translatable.ScrollPosition', { extend: Ext.util.translatable.Dom, alias: 'translatable.scrollposition', constructor: function(config) { if (config && config.element) { this.x = config.element.getScrollLeft(); this.y = config.element.getScrollTop(); } this.callParent([ config ]); }, translateAnimated: function() { var element = this.getElement(); this.x = element.getScrollLeft(); this.y = element.getScrollTop(); this.callParent(arguments); }, doTranslate: function(x, y) { var element = this.getElement(); element.setScrollLeft(Math.round(x)); element.setScrollTop(Math.round(y)); }, getPosition: function() { var me = this, position = me.position, element = me.getElement(); position.x = element.getScrollLeft(); position.y = element.getScrollTop(); return position; } }); Ext.define('Ext.scroll.Scroller', { extend: Ext.Evented, alias: 'scroller.scroller', mixins: [ Ext.mixin.Factoryable, Ext.mixin.Bufferable ], factoryConfig: { defaultType: 'scroller' }, bufferableMethods: { onDomScrollEnd: 100 }, isScroller: true, config: { direction: undefined, element: undefined, scrollbars: null, snapSelector: null, snapOffset: null, msSnapInterval: null, x: true, y: true, scrollElement: null, size: null, spacerXY: null, touchAction: null }, snappableCls: Ext.baseCSSPrefix + 'scroller-snappable', elementCls: Ext.baseCSSPrefix + 'scroller', spacerCls: Ext.baseCSSPrefix + 'scroller-spacer', noScrollbarsCls: Ext.baseCSSPrefix + 'no-scrollbars', statics: { create: function(config, type) { return Ext.Factory.scroller(config, type); }, getScrollingElement: function() { var doc = document, standard = this.$standardScrollElement, el = doc.scrollingElement, iframe, frameDoc; if (el) { return el; } if (standard === undefined) { iframe = document.createElement('iframe'); iframe.style.height = '1px'; document.body.appendChild(iframe); frameDoc = iframe.contentWindow.document; frameDoc.write('
x
'); frameDoc.close(); standard = frameDoc.documentElement.scrollHeight > frameDoc.body.scrollHeight; iframe.parentNode.removeChild(iframe); this.$standardScrollElement = standard; } return standard ? doc.documentElement : doc.body; }, initViewportScroller: function() { var scroller = Ext.getViewportScroller(); if (!scroller.getElement()) { scroller.setElement(Ext.getBody()); } } }, constructor: function(config) { var me = this; me.position = { x: 0, y: 0 }; me.callParent([ config ]); }, destroy: function() { var me = this, partners = me._partners, key; Ext.undefer(me.restoreTimer); me.setX(Ext.emptyString); me.setY(Ext.emptyString); if (me._spacer) { me._spacer.destroy(); } if (me.scrollListener) { me.scrollListener.destroy(); } if (partners) { for (key in partners) { me.removePartner(partners[key].scroller); } } me.setElement(null); me._partners = me.component = null; if (me.translatable) { me.translatable.destroy(); me.translatable = null; } me.removeSnapStylesheet(); me.callParent(); }, addPartner: function(partner, axis) { var me = this, partners = me._partners || (me._partners = {}), otherPartners = partner._partners || (partner._partners = {}); axis = me.axisConfigs[axis || 'both']; partners[partner.getId()] = { scroller: partner, axes: axis }; otherPartners[me.getId()] = { scroller: me, axes: axis }; }, applyElement: function(element, oldElement) { var me = this; if (oldElement && me.scrollListener) { me.scrollListener.destroy(); } if (element) { if (typeof element === 'string' && !Ext.get(element)) { Ext.raise("Cannot create Ext.scroll.Scroller instance. " + "Element with id '" + element + "' not found."); } element = Ext.get(element); } return element; }, applySize: function(size, oldSize) { var x, y; if (size === null || typeof size === 'number') { x = y = size; } else if (size) { x = size.x; y = size.y; } if (x === null) { x = 0; } else if (x === undefined) { x = (oldSize ? oldSize.x : 0); } if (y === null) { y = 0; } else if (y === undefined) { y = (oldSize ? oldSize.y : 0); } if (!oldSize || x !== oldSize.x || y !== oldSize.y) { return { x: x, y: y }; } }, getClientSize: function() { var dom = this.getElement().dom; return { x: dom.clientWidth, y: dom.clientHeight }; }, getScrollbarSize: function() { var me = this, width = 0, height = 0, element = me.getElement(), dom, x, y, hasXScroll, hasYScroll, scrollbarSize; if (element && !element.destroyed) { x = me.getX(); y = me.getY(); dom = element.dom; if (x || y) { scrollbarSize = Ext.getScrollbarSize(); } if (x === 'scroll') { hasXScroll = true; } else if (x) { hasXScroll = dom.scrollWidth > dom.clientWidth; } if (y === 'scroll') { hasYScroll = true; } else if (y) { hasYScroll = dom.scrollHeight > dom.clientHeight; } if (hasXScroll) { height = scrollbarSize.height; } if (hasYScroll) { width = scrollbarSize.width; } } return { width: width, height: height }; }, getPosition: function() { var me = this; if (me.positionDirty) { me.updateDomScrollPosition(); } return me.position; }, getSize: function() { var element = this.getElement(), size, dom; if (element && !element.destroyed) { dom = element.dom; size = { x: dom.scrollWidth, y: dom.scrollHeight }; } else { size = { x: 0, y: 0 }; } return size; }, getMaxPosition: function() { var element = this.getElement(), x = 0, y = 0, dom; if (element && !element.destroyed) { 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.destroyed) { dom = element.dom; if (me.getX()) { x = dom.scrollWidth - dom.clientWidth; } if (me.getY()) { y = dom.scrollHeight - dom.clientHeight; } } return { x: x, y: y }; }, refresh: function() { this.positionDirty = true; 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); }, ensureVisible: function(el, options) { var me = this, position = me.getPosition(), highlight, newPosition, ret; if (el) { if (el && el.element && !el.isElement) { options = el; el = options.element; } options = options || {}; highlight = options.highlight; newPosition = me.getEnsureVisibleXY(el, options); if (newPosition.y !== position.y || newPosition.x !== position.x) { if (highlight) { me.on({ scrollend: 'doHighlight', scope: me, single: true, args: [ el, highlight ] }); } ret = me.doScrollTo(newPosition.x, newPosition.y, options.animation); } else { if (highlight) { me.doHighlight(el, highlight); } ret = Ext.Deferred.getCachedResolved(); } } else { ret = Ext.Deferred.getCachedRejected(); } return ret; }, scrollIntoView: function(el, hscroll, animate, highlight) { return this.ensureVisible(el, { animation: animate, highlight: highlight, x: hscroll }); }, isInView: function(el) { return this.doIsInView(el); }, scrollTo: function(x, y, animation) { var maxPosition; if (x) { if (x.length) { animation = y; y = x[1]; x = x[0]; } else if (typeof x !== 'number') { animation = 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; } } return this.doScrollTo(x, y, animation); }, 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); } }, updateScrollbars: function(scrollbars, oldScrollbars) { this.syncScrollbarCls(); }, updateSize: function(size) { var me = this, element = me.getElement(), x = size.x, y = size.y, spacer; if (element) { me.positionDirty = true; spacer = me.getSpacer(); if (!x && !y) { spacer.hide(); } else { if (x > 0) { x -= 1; } if (y > 0) { y -= 1; } me.setSpacerXY({ x: x, y: y }); spacer.show(); } } }, updateMsSnapInterval: function() { this.initMsSnapInterval(); }, updateSnapSelector: function() { this.initSnap(); }, updateSnapOffset: function() { this.initSnap(); }, updateTouchAction: function(touchAction) { var element = this.getElement(); if (element) { element.setTouchAction(touchAction); } }, updateElement: function(element, oldElement) { var me = this, touchAction = me.getTouchAction(), scrollListener = me.scrollListener, elementCls = me.elementCls, eventSource, scrollEl; if (scrollListener) { scrollListener.destroy(); me.scrollListener = null; me.setScrollElement(null); } if (oldElement && !oldElement.destroyed) { oldElement.setStyle('overflow', 'hidden'); oldElement.removeCls(elementCls); } if (element) { if (element.dom === document.documentElement || element.dom === document.body) { eventSource = Ext.getWin(); scrollEl = Ext.scroll.Scroller.getScrollingElement(); } else { scrollEl = eventSource = element; } me.setScrollElement(Ext.get(scrollEl)); me.scrollListener = eventSource.on({ scroll: me.onDomScroll, scope: me, destroyable: true }); if (touchAction) { element.setTouchAction(touchAction); } me.initXStyle(); me.initYStyle(); element.addCls(elementCls); me.initSnap(); me.initMsSnapInterval(); me.syncScrollbarCls(); } }, updateX: function(x) { this.initXStyle(); }, updateY: function(y) { this.initYStyle(); }, 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: { axisConfigs: { x: { x: true }, y: { y: true }, both: { x: true, y: true } }, getEnsureVisibleXY: function(el, options) { var position = this.getPosition(), viewport = this.component ? this.component.getScrollableClientRegion() : this.getElement(), newPosition, align; if (el && el.element && !el.isElement) { options = el; el = options.element; } options = options || {}; align = options.align; if (align) { if (Ext.isString(align)) { align = { x: options.x === false ? null : align, y: options.y === false ? null : align }; } else if (Ext.isObject(align)) { if (align.x && options.x === false) { align.x = null; } if (align.y && options.y === false) { align.y = null; } } } newPosition = Ext.fly(el).getScrollIntoViewXY(viewport, position.x, position.y, align); newPosition.x = options.x === false ? position.x : newPosition.x; newPosition.y = options.y === false ? position.y : newPosition.y; return newPosition; }, getSpacer: function() { var me = this, spacer = me._spacer, element; if (!spacer) { element = me.getElement(); spacer = me._spacer = element.createChild({ cls: me.spacerCls, role: 'presentation' }, element.dom.firstChild); spacer.setVisibilityMode(2); spacer.hide(); element.position(); } return spacer; }, applySpacerXY: function(pos, oldPos) { if (oldPos && pos.x === oldPos.x && pos.y === oldPos.y) { pos = undefined; } return pos; }, updateSpacerXY: function(pos) { var me = this, spacer = me.getSpacer(), sStyle = spacer.dom.style, scrollHeight = pos.y, shortfall; sStyle.marginTop = ''; me.translateSpacer(pos.x, me.constrainScrollRange(scrollHeight)); sStyle.lineHeight = Number(!parseInt(sStyle.lineHeight, 10)) + 'px'; if (scrollHeight > 1000000) { shortfall = scrollHeight - me.getElement().dom.scrollHeight; if (shortfall > 0) { sStyle.marginTop = Math.min(shortfall, me.maxSpacerMargin || 0) + 'px'; } } }, translateSpacer: function(x, y) { this.getSpacer().translate(x, y); }, doIsInView: function(el, skipCheck) { var me = this, c = me.component, result = { x: false, y: false }, elRegion, myEl = me.getElement(), myElRegion; if (el && (skipCheck || (myEl.contains(el) || (c && c.owns(el))))) { myElRegion = myEl.getRegion(); elRegion = Ext.fly(el).getRegion(); result.x = elRegion.right > myElRegion.left && elRegion.left < myElRegion.right; result.y = elRegion.bottom > myElRegion.top && elRegion.top < myElRegion.bottom; } return result; }, contains: function(component) { var el = this.getElement(), owner = component; while (owner && owner !== Ext.Viewport) { if (el.contains(owner.el)) { return true; } owner = owner.getRefOwner(); } return false; }, constrainScrollRange: function(scrollRange) { if (scrollRange < 1000000) { return scrollRange; } if (!this.maxSpacerTranslate) { var maxScrollHeight = Math.pow(2, 32), tooHigh = maxScrollHeight, tooLow = 500, scrollTest = Ext.getBody().createChild({ style: { position: 'absolute', left: '-10000px', top: '0', width: '500px', height: '500px' }, cn: { cls: this.spacerCls } }, null, true), stretcher = Ext.get(scrollTest.firstChild), sStyle = stretcher.dom.style; stretcher.translate(0, maxScrollHeight - 1); sStyle.lineHeight = Number(!parseInt(sStyle.lineHeight, 10)) + 'px'; while (tooHigh !== tooLow + 1) { stretcher.translate(0, (maxScrollHeight = tooLow + Math.floor((tooHigh - tooLow) / 2))); sStyle.lineHeight = Number(!parseInt(sStyle.lineHeight, 10)) + 'px'; if (scrollTest.scrollHeight < maxScrollHeight) { tooHigh = maxScrollHeight; } else { tooLow = maxScrollHeight; } } stretcher.translate(0, Ext.scroll.Scroller.prototype.maxSpacerTranslate = tooLow); tooHigh = tooLow * 2; while (tooHigh !== tooLow + 1) { stretcher.dom.style.marginTop = ((maxScrollHeight = tooLow + Math.floor((tooHigh - tooLow) / 2))) + 'px'; sStyle.lineHeight = Number(!parseInt(sStyle.lineHeight, 10)) + 'px'; if (scrollTest.scrollHeight < maxScrollHeight) { tooHigh = maxScrollHeight; } else { tooLow = maxScrollHeight; } } Ext.fly(scrollTest).destroy(); Ext.scroll.Scroller.prototype.maxSpacerMargin = tooLow - Ext.scroll.Scroller.prototype.maxSpacerTranslate; } return Math.min(scrollRange, this.maxSpacerTranslate); }, convertX: function(x) { return x; }, doHighlight: function(el, highlight) { if (highlight !== true) { Ext.fly(el).highlight(highlight); } else { Ext.fly(el).highlight(); } }, doScrollTo: function(x, y, animate) { var me = this, element = me.getScrollElement(), maxPosition, dom, xInf, yInf, ret, translatable, deferred; if (element && !element.destroyed) { dom = element.dom; xInf = (x === Infinity); yInf = (y === Infinity); if (xInf || yInf) { maxPosition = me.getMaxPosition(); if (xInf) { x = maxPosition.x; } if (yInf) { y = maxPosition.y; } } if (x !== null) { x = me.convertX(x); } if (animate) { translatable = me.translatable; if (!translatable) { me.translatable = translatable = new Ext.util.translatable.ScrollPosition({ element: element }); } deferred = new Ext.Deferred(); translatable.on('animationend', function() { if (me.destroyed) { deferred.reject(); } else { deferred.resolve(); } }, Ext.global, { single: true, onFrame: true }); translatable.translate(x, y, animate); ret = deferred.promise; } else { if (y != null) { dom.scrollTop = y; } if (x != null) { dom.scrollLeft = x; } ret = Ext.Deferred.getCachedResolved(); } me.positionDirty = true; } else { ret = Ext.Deferred.getCachedRejected(); } return ret; }, fireScrollStart: function(x, y, xDelta, yDelta) { var me = this, component = me.component; me.invokePartners('onPartnerScrollStart', x, y, xDelta, yDelta); me.startX = x - xDelta; me.startY = y - yDelta; 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, xDelta, yDelta) { var me = this, component = me.component; me.invokePartners('onPartnerScroll', x, y, xDelta, yDelta); if (me.hasListeners.scroll) { me.fireEvent('scroll', me, x, y, xDelta, yDelta); } if (component && component.onScrollMove) { component.onScrollMove(x, y); } Ext.GlobalEvents.fireEvent('scroll', me, x, y, xDelta, yDelta); }, fireScrollEnd: function(x, y, xDelta, yDelta) { var me = this, component = me.component, dx = x - me.startX, dy = y - me.startY; me.startX = me.startY = null; me.invokePartners('onPartnerScrollEnd', x, y, xDelta, yDelta); if (me.hasListeners.scrollend) { me.fireEvent('scrollend', me, x, y, dx, dy); } if (component && component.onScrollEnd) { component.onScrollEnd(x, y); } Ext.GlobalEvents.fireEvent('scrollend', me, x, y, dx, dy); }, getElementScroll: function(element) { return element.getScroll(); }, initSnap: function() { var me = this, snapOffset = me.getSnapOffset(), snapSelector = me.getSnapSelector(), element = me.getElement(), offsetX, offsetY, snapCoordinate; if (element && snapSelector) { element.addCls(me.snappableCls); me.removeSnapStylesheet(); if (snapOffset) { offsetX = snapOffset.x || 0; offsetY = snapOffset.y || 0; if (offsetX) { offsetX = -offsetX + 'px'; } if (offsetY) { offsetY = -offsetY + 'px'; } } snapCoordinate = offsetX + ' ' + offsetY + ';'; me.snapStylesheet = Ext.util.CSS.createStyleSheet('#' + element.id + ' ' + snapSelector + '{-webkit-scroll-snap-coordinate:' + snapCoordinate + 'scroll-snap-coordinate:' + snapCoordinate + '}'); } }, initMsSnapInterval: function() { var element = this.getElement(), interval, x, y, style; if (element) { interval = this.getMsSnapInterval(); if (interval) { x = interval.x; y = interval.y; style = element.dom.style; if (x) { style['-ms-scroll-snap-points-x'] = 'snapInterval(0px, ' + x + 'px)'; } if (y) { style['-ms-scroll-snap-points-y'] = 'snapInterval(0px, ' + y + 'px)'; } } } }, initXStyle: function() { var element = this.getElement(), x = this.getX(); if (element && element.dom) { if (!x) { x = 'hidden'; } else if (x === true) { x = 'auto'; } element.setStyle('overflow-x', x); } }, initYStyle: function() { var element = this.getElement(), y = this.getY(); if (element && element.dom) { if (!y) { y = 'hidden'; } else if (y === true) { y = 'auto'; } element.setStyle('overflow-y', y); } }, invokePartners: function(method, x, y, xDelta, yDelta) { var me = this, partners = me._partners, partner, id, axes; if (!me.suspendSync) { me.invokingPartners = true; for (id in partners) { axes = partners[id].axes; partner = partners[id].scroller; if (!partner.invokingPartners && (xDelta && axes.x || yDelta && axes.y)) { partner[method](me, axes.x ? x : null, axes.y ? y : null, xDelta, yDelta); } } me.invokingPartners = false; } }, suspendPartnerSync: function() { this.suspendSync = (this.suspendSync || 0) + 1; }, resumePartnerSync: function(syncNow) { var me = this, position; if (me.suspendSync) { me.suspendSync--; } if (!me.suspendSync && syncNow) { position = me.getPosition(); me.invokePartners('onPartnerScroll', position.x, position.y); me.invokePartners('onPartnerScrollEnd', position.x, position.y); } }, readPosition: function(position) { var me = this, element = me.getScrollElement(), elScroll; position = position || {}; if (element && !element.destroyed) { elScroll = me.getElementScroll(element); position.x = elScroll.left; position.y = elScroll.top; } return position; }, updateDomScrollPosition: function(silent) { var me = this, position = me.position, oldX = position.x, oldY = position.y, x, y, xDelta, yDelta; me.readPosition(position); x = position.x; y = position.y; me.positionDirty = false; if (!silent) { xDelta = x - oldX; yDelta = y - oldY; if (xDelta || yDelta) { if (!me.isScrolling) { me.isScrolling = Ext.isScrolling = true; me.fireScrollStart(x, y, xDelta, yDelta); } me.fireScroll(x, y, xDelta, yDelta); me.onDomScrollEnd(x, y, xDelta, yDelta); } } return position; }, syncWithPartners: function() { var me = this, partners = me._partners, id, partner, position; me.suspendPartnerSync(); for (id in partners) { partner = partners[id].scroller; position = partner.getPosition(); me.onPartnerScroll(partner, position.x, position.y); } me.resumePartnerSync(); }, syncScrollbarCls: function() { var element = this.getElement(); if (element) { element.toggleCls(this.noScrollbarsCls, this.getScrollbars() === false); } }, onDomScroll: function() { var hasTimer = !!this.restoreTimer; this.updateDomScrollPosition(hasTimer); if (hasTimer) { Ext.undefer(this.onDomScrollEnd.timer); return; } }, doOnDomScrollEnd: function(x, y, xDelta, yDelta) { var me = this; if (me.destroying || me.destroyed) { return; } me.isScrolling = Ext.isScrolling = false; if (x === undefined) { return; } me.trackingScrollLeft = x; me.trackingScrollTop = y; me.fireScrollEnd(x, y, xDelta, yDelta); }, onPartnerScrollStart: function(partner, x, y, xDelta, yDelta) { this.isScrolling = true; this.fireScrollStart(x, y, xDelta, yDelta); }, onPartnerScroll: function(partner, x, y, xDelta, yDelta) { this.doScrollTo(x, y, false); this.updateDomScrollPosition(true); this.fireScroll(x, y, xDelta, yDelta); }, onPartnerScrollEnd: function(partner, x, y, xDelta, yDelta) { this.cancelOnDomScrollEnd(); this.doOnDomScrollEnd(x, y, xDelta, yDelta); }, removeSnapStylesheet: function() { var stylesheet = this.snapStylesheet; if (stylesheet) { Ext.util.CSS.removeStyleSheet(stylesheet); this.snapStylesheet = null; } }, restoreState: function() { var me = this, el = me.getScrollElement(); if (el) { if (me.trackingScrollTop !== undefined) { if (!me.restoreTimer) { me.restoreTimer = Ext.defer(function() { me.restoreTimer = null; }, 50); } me.doScrollTo(me.trackingScrollLeft, me.trackingScrollTop, false); } } } } }, function(Scroller) { Ext.getViewportScroller = function() { var scroller = Scroller.viewport; if (!scroller) { Scroller.viewport = scroller = new Scroller(); Scroller.initViewportScroller(); } return scroller; }; Ext.setViewportScroller = function(scroller) { if (Scroller.viewport !== scroller) { Ext.destroy(Scroller.viewport); if (scroller && !scroller.isScroller) { scroller = new Scroller(scroller); } Scroller.viewport = scroller; } }; Ext.onReady(function() { Scroller.initViewportScrollerTimer = Ext.defer(Scroller.initViewportScroller, 100); }); }); Ext.define('Ext.ProgressBase', { mixinId: 'progressbase', config: { value: 0, textTpl: null }, applyTextTpl: function(textTpl) { if (!textTpl.isTemplate) { textTpl = new Ext.XTemplate(textTpl); } return textTpl; }, applyValue: function(value) { return value || 0; } }); Ext.define('Ext.Progress', { extend: Ext.Gadget, xtype: [ 'progress', 'progressbarwidget' ], alternateClassName: 'Ext.ProgressBarWidget', mixins: [ Ext.ProgressBase ], config: { text: null, animate: false }, cachedConfig: { textCls: Ext.baseCSSPrefix + 'progress-text', cls: null }, baseCls: Ext.baseCSSPrefix + 'progress', template: [ { reference: 'backgroundEl' }, { reference: 'barEl', cls: Ext.baseCSSPrefix + 'progress-bar', children: [ { reference: 'textEl' } ] } ], defaultBindProperty: 'value', updateCls: function(cls, oldCls) { var el = this.element; if (oldCls) { el.removeCls(oldCls); } if (cls) { el.addCls(cls); } }, updateUi: function(ui, oldUi) { var element = this.element, barEl = this.barEl, baseCls = this.baseCls + '-'; this.callParent([ ui, oldUi ]); if (oldUi) { element.removeCls(baseCls + oldUi); barEl.removeCls(baseCls + 'bar-' + oldUi); } element.addCls(baseCls + ui); barEl.addCls(baseCls + 'bar-' + ui); }, updateTextCls: function(textCls) { this.backgroundEl.addCls(textCls + ' ' + textCls + '-back'); this.textEl.addCls(textCls); }, updateValue: function(value, oldValue) { var me = this, textTpl = me.getTextTpl(); if (textTpl) { me.setText(textTpl.apply({ value: value, percent: Math.round(value * 100) })); } if (!me.isConfiguring && me.getAnimate()) { me.stopBarAnimation(); me.startBarAnimation(Ext.apply({ from: { width: (oldValue * 100) + '%' }, to: { width: (value * 100) + '%' } }, me.animate)); } else { me.barEl.setStyle('width', (value * 100) + '%'); } }, updateText: function(text) { this.backgroundEl.setHtml(text); this.textEl.setHtml(text); }, doDestroy: function() { this.stopBarAnimation(); this.callParent(); }, privates: { startBarAnimation: Ext.privateFn, stopBarAnimation: Ext.privateFn } }); 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, mixins: [ Ext.mixin.Factoryable ], factoryConfig: { type: 'animation' }, isAnimation: true, config: { name: '', element: null, before: null, from: {}, to: {}, after: null, states: {}, duration: 300, easing: 'linear', iteration: 1, direction: 'normal', delay: 0, onBeforeStart: null, callback: null, onEnd: null, onBeforeEnd: null, scope: null, reverse: null, preserveEndState: false, replacePrevious: true }, STATE_FROM: '0%', STATE_TO: '100%', DIRECTION_UP: 'up', DIRECTION_TOP: 'top', DIRECTION_DOWN: 'down', DIRECTION_BOTTOM: 'bottom', 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; }, updateCallback: function(callback) { if (callback) { this.setOnEnd(callback); } }, end: function() { this.stop(); }, stop: function() { this.fireEvent('stop', this); }, destroy: function() { this.destroying = true; this.stop(); this.callParent(); this.destroying = false; this.destroyed = true; }, 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 me = this, states = me.getStates(), statesData = {}, before = me.getBefore(), after = me.getAfter(), from = states[me.STATE_FROM], to = states[me.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; } } return { before: before ? before.getData() : {}, after: after ? after.getData() : {}, states: statesData, from: fromData, to: toData, duration: me.getDuration(), iteration: me.getIteration(), direction: me.getDirection(), easing: me.getEasing(), delay: me.getDelay(), onEnd: me.getOnEnd(), onBeforeEnd: me.getOnBeforeEnd(), onBeforeStart: me.getOnBeforeStart(), scope: me.getScope(), preserveEndState: me.getPreserveEndState(), replacePrevious: me.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', top: 'down', down: 'up', bottom: '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, offsetPct, fromX, fromY, toX, toY; if (typeof offset === 'string') { offsetPct = true; offset = parseFloat(offset); } if (reverse) { direction = this.reverseDirectionMap[direction]; } switch (direction) { case this.DIRECTION_UP: case this.DIRECTION_TOP: if (offsetPct) { offset = box.height * offset / 100; }; if (out) { translateY = containerBox.top - box.top - box.height - offset; } else { translateY = containerBox.bottom - box.bottom + box.height + offset; }; break; case this.DIRECTION_DOWN: case this.DIRECTION_BOTTOM: if (offsetPct) { offset = box.height * offset / 100; }; 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 (offsetPct) { offset = box.width * offset / 100; }; 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 (offsetPct) { offset = box.width * offset / 100; }; 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 me = this, from = me.getFrom(), to = me.getTo(), direction = me.getDirection(), out = me.getOut(), half = me.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: case this.DIRECTION_TOP: if (out) { toRotateX = rotate; } else { fromRotateX = -rotate; }; break; case this.DIRECTION_DOWN: case this.DIRECTION_BOTTOM: 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(); } }); 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', { 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) { defaultClass = Ext.ClassManager.getByAlias('animation.' + type); if (!defaultClass) { Ext.Logger.error("Invalid animation type of: '" + type + "'"); } } return Ext.factory(config, defaultClass); } }); Ext.define('Ext.app.EventDomain', { 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.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.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 me = this, ret; ret = doFireEvent.apply(me, arguments); if (ret !== false && !me.destroyed && !me.isSuspended(ev)) { ret = domain.dispatch(me, 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; this.callParent(); } }); Ext.define('Ext.app.domain.Component', { extend: Ext.app.EventDomain, singleton: true, 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([ target, ev, args ]); }, match: function(target, selector) { return target.is(selector); } }); Ext.define('Ext.app.EventBus', { singleton: true, 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, 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.route.Handler', { lazy: false, statics: { fromRouteConfig: function(config, scope) { var handler = { action: config.action, before: config.before, lazy: config.lazy, exit: config.exit, scope: scope, single: config.single }; return new this(handler); } }, constructor: function(config) { Ext.apply(this, config); } }); Ext.define('Ext.route.Action', { config: { actions: null, befores: null, urlParams: [] }, started: false, stopped: false, constructor: function(config) { var me = this; me.deferred = new Ext.Deferred(); me.resume = me.resume.bind(me); me.stop = me.stop.bind(me); me.initConfig(config); me.callParent([ config ]); }, applyActions: function(actions) { if (actions) { actions = Ext.Array.from(actions); } return actions; }, applyBefores: function(befores) { if (befores) { befores = Ext.Array.from(befores); } return befores; }, destroy: function() { this.deferred = null; this.setBefores(null).setActions(null).setUrlParams(null); this.callParent(); }, resume: function() { return this.next(); }, stop: function() { this.stopped = true; return this.done(); }, next: function() { var me = this, actions = me.getActions(), befores = me.getBefores(), urlParams = me.getUrlParams(), config, ret, args; if (Ext.isArray(urlParams)) { args = urlParams.slice(); } else { args = [ urlParams ]; } if (me.stopped || (befores ? !befores.length : true) && (actions ? !actions.length : true)) { me.done(); } else { if (befores && befores.length) { config = befores.shift(); args.push(me); ret = Ext.callback(config.fn, config.scope, args); if (ret && ret.then) { ret.then(function(arg) { me.resume(arg); }, function(arg) { me.stop(arg); }); } } else if (actions && actions.length) { config = actions.shift(); Ext.callback(config.fn, config.scope, args); me.next(); } else { me.next(); } } return me; }, run: function() { var deferred = this.deferred; if (!this.started) { this.next(); this.started = true; } return deferred.promise; }, done: function() { var deferred = this.deferred; if (this.stopped) { deferred.reject(); } else { deferred.resolve(); } this.destroy(); return this; }, before: function(first, fn, scope) { if (!Ext.isBoolean(first)) { scope = fn; fn = first; first = false; } var befores = this.getBefores(), config = { fn: fn, scope: scope }; if (this.destroyed) { Ext.raise('This action has has already resolved and therefore will never execute this function.'); return; } if (befores) { if (first) { befores.unshift(config); } else { befores.push(config); } } else { this.setBefores(config); } return this; }, action: function(first, fn, scope) { if (!Ext.isBoolean(first)) { scope = fn; fn = first; first = false; } var actions = this.getActions(), config = { fn: fn, scope: scope }; if (this.destroyed) { Ext.raise('This action has has already resolved and therefore will never execute this function.'); return; } if (actions) { if (first) { actions.unshift(config); } else { actions.push(config); } } else { this.setActions(config); } return this; }, then: function(resolve, reject) { if (this.destroyed) { Ext.raise('This action has has already resolved and therefore will never execute either function.'); return; } return this.deferred.then(resolve, reject); } }); Ext.define('Ext.route.Route', { config: { name: null, url: null, allowInactive: false, conditions: {}, caseInsensitive: false, handlers: [], types: { cached: true, $value: { alpha: { re: '([a-zA-Z]+)' }, alphanum: { re: '([a-zA-Z0-9]+|[0-9]+(?:\\.[0-9]+)?|[0-9]*(?:\\.[0-9]+){1})', parse: function(value) { var test; if (value && this.numRe.test(value)) { test = parseFloat(value); if (!isNaN(test)) { value = test; } } return value; } }, num: { re: '([0-9]+(?:\\.[0-9]+)?|[0-9]*(?:\\.[0-9]+){1})', parse: function(value) { if (value) { value = parseFloat(value); } return value; } }, '...': { re: '(.+)?', split: '/', parse: function(values) { var length, i, value; if (values) { length = values.length; for (i = 0; i < length; i++) { value = parseFloat(values[i]); if (!isNaN(value)) { values[i] = value; } } } return values; } } } } }, defaultMatcher: '([%a-zA-Z0-9\\-\\_\\s,]+)', numRe: /^[0-9]*(?:\.[0-9]*)?$/, typeParamRegex: /:{([0-9A-Za-z\_]+)(?::?([0-9A-Za-z\_]+|.{3})?)}/g, optionalGroupRegex: /\((.+?)\)/g, paramMatchingRegex: /:([0-9A-Za-z\_]+)/g, isRoute: true, constructor: function(config) { var me = this, url; this.initConfig(config); url = me.getUrl().replace(me.optionalGroupRegex, function(match, middle) { return '(?:' + middle + ')?'; }); if (url.match(me.typeParamRegex)) { me.handleNamedPattern(url); } else { me.handlePositionalPattern(url); } }, handlePositionalPattern: function(url) { var me = this; me.paramsInMatchString = url.match(me.paramMatchingRegex) || []; me.matcherRegex = me.createMatcherRegex(url); me.mode = 'positional'; }, handleNamedPattern: function(url) { var me = this, typeParamRegex = me.typeParamRegex, conditions = me.getConditions(), types = me.getTypes(), defaultMatcher = me.defaultMatcher, params = {}, re = url.replace(typeParamRegex, function(match, param, typeMatch) { var type = typeMatch && types[typeMatch], matcher = conditions[param] || type || defaultMatcher; if (params[param]) { Ext.raise('"' + param + '" already defined in route "' + url + '"'); } if (typeMatch && !type) { Ext.raise('Unknown parameter type "' + typeMatch + '" in route "' + url + '"'); } if (Ext.isObject(matcher)) { matcher = matcher.re; } params[param] = { matcher: matcher, type: typeMatch }; return matcher; }); if (re.search(me.paramMatchingRegex) !== -1) { Ext.raise('URL parameter mismatch. Positional url parameter found while in named mode.'); } me.paramsInMatchString = params; me.matcherRegex = new RegExp('^' + re + '$', me.getCaseInsensitive() ? 'i' : ''); me.mode = 'named'; }, recognize: function(url) { var me = this, recognized = me.recognizes(url), handlers, length, hasHandler, i, handler, matches, urlParams, arg, params; if (recognized) { handlers = me.getHandlers(); length = handlers.length; for (i = 0; i < length; i++) { handler = handlers[i]; if (handler.lastToken !== url) { hasHandler = true; break; } } if (!hasHandler && url === me.lastToken) { return true; } matches = me.matchesFor(url); urlParams = me.getUrlParams(url); return Ext.applyIf(matches, { historyUrl: url, urlParams: urlParams }); } return false; }, getUrlParams: function(url) { if (this.mode === 'named') { return this.getNamedUrlParams(url); } else { return this.getPositionalUrlParams(url); } }, getPositionalUrlParams: function(url) { var params = [], conditions = this.getConditions(), keys = this.paramsInMatchString, values = url.match(this.matcherRegex), length = keys.length, i, key, type, value; values.shift(); for (i = 0; i < length; i++) { key = keys[i]; value = values[i]; if (conditions[key]) { type = conditions[key]; } else if (key[0] === ':') { key = key.substr(1); if (conditions[key]) { type = conditions[key]; } } value = this.parseValue(value, type); if (Ext.isDefined(value) && value !== '') { if (Ext.isArray(value)) { params.push.apply(params, value); } else { params.push(value); } } } return params; }, getNamedUrlParams: function(url) { var conditions = this.getConditions(), types = this.getTypes(), params = {}, keys = this.paramsInMatchString, values = url.match(this.matcherRegex), name, obj, value, type, condition; values.shift(); for (name in keys) { obj = keys[name]; value = values.shift(); condition = conditions[name]; type = types[obj.type]; if (condition || type) { type = Ext.merge({}, condition, types[obj.type]); } params[name] = this.parseValue(value, type); } return params; }, parseValue: function(value, type) { if (type) { if (value && type.split) { value = value.split(type.split); if (!value[0]) { value.shift(); } if (!value[value.length - 1]) { value.pop(); } } if (type.parse) { value = type.parse.call(this, value); } } if (!value && Ext.isString(value)) { value = undefined; } return value; }, recognizes: function(url) { return this.matcherRegex.test(url); }, execute: function(token, argConfig) { var me = this, allowInactive = me.getAllowInactive(), handlers = me.getHandlers(), queue = Ext.route.Router.getQueueRoutes(), length = handlers.length, befores = [], actions = [], urlParams = (argConfig && argConfig.urlParams) || [], i, handler, scope, action, promises, single, remover; me.lastToken = token; if (!queue) { promises = []; } return new Ext.Promise(function(resolve, reject) { if (argConfig === false) { reject(); } else { if (queue) { action = new Ext.route.Action({ urlParams: urlParams }); } for (i = 0; i < length; i++) { handler = handlers[i]; if (token != null && handler.lastToken === token) { continue; } scope = handler.scope; handler.lastToken = token; if (!allowInactive && scope.isActive && !scope.isActive()) { continue; } if (!queue) { action = new Ext.route.Action({ urlParams: urlParams }); } single = handler.single; if (handler.before) { action.before(handler.before, scope); } if (handler.action) { action.action(handler.action, scope); } if (single) { remover = Ext.bind(me.removeHandler, me, [ null, handler ]); if (single === true) { if (handler.action) { action.action(remover, me); } else { action.before(function() { remover(); return Ext.Promise.resolve(); }, me); } } else { action.before(single === 'before', function() { remover(); return Ext.Promise.resolve(); }, me); } } if (!queue) { if (Ext.fireEvent('beforeroute', action, me) === false) { action.destroy(); } else { promises.push(action.run()); } } } if (queue) { if (Ext.fireEvent('beforeroute', action, me) === false) { action.destroy(); reject(); } else { action.run().then(resolve, reject); } } else { Ext.Promise.all(promises).then(resolve, reject); } } }); }, matchesFor: function(url) { var params = {}, keys = this.mode === 'named' ? Ext.Object.getKeys(this.paramsInMatchString) : this.paramsInMatchString, values = url.match(this.matcherRegex), length = keys.length, i; values.shift(); for (i = 0; i < length; i++) { params[keys[i].replace(':', '')] = values[i]; } return params; }, createMatcherRegex: function(url) { var me = this, paramsInMatchString = me.paramsInMatchString, conditions = me.getConditions(), defaultMatcher = me.defaultMatcher, length = paramsInMatchString.length, modifiers = me.getCaseInsensitive() ? 'i' : '', i, param, matcher; if (url === '*') { url = url.replace('*', '\\*'); } else { for (i = 0; i < length; i++) { param = paramsInMatchString[i]; if (conditions[param]) { matcher = conditions[param]; } else if (param[0] === ':' && conditions[param.substr(1)]) { matcher = conditions[param.substr(1)]; } else { matcher = defaultMatcher; } if (Ext.isObject(matcher)) { matcher = matcher.re; } url = url.replace(new RegExp(param), matcher || defaultMatcher); } } return new RegExp('^' + url + '$', modifiers); }, addHandler: function(handler) { var handlers = this.getHandlers(); if (!handler.isInstance) { handler = new Ext.route.Handler(handler); } handlers.push(handler); return handler.route = this; }, removeHandler: function(scope, handler) { var handlers = this.getHandlers(), length = handlers.length, newHandlers = [], i, item; for (i = 0; i < length; i++) { item = handlers[i]; if (handler) { if (item !== handler) { newHandlers.push(item); } } else if (item.scope !== scope) { newHandlers.push(item); } } this.setHandlers(newHandlers); return this; }, clearLastTokens: function() { var handlers = this.getHandlers(), length = handlers.length, i; for (i = 0; i < length; i++) { handlers[i].lastToken = null; } this.lastToken = null; }, onExit: function() { var me = this, handlers = me.getHandlers(), allowInactive = me.getAllowInactive(), length = handlers.length, action = new Ext.route.Action({ urlParams: [ me.lastToken ] }), i, handler, scope; me.clearLastTokens(); for (i = 0; i < length; i++) { handler = handlers[i]; if (handler.exit) { scope = handler.scope; if (!allowInactive && scope.isActive && !scope.isActive()) { continue; } action.action(handler.exit, scope); } } if (Ext.fireEvent('beforerouteexit', action, me) === false) { action.destroy(); } else { action.run(); } } }); 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.History', { singleton: true, alternateClassName: 'Ext.History', mixins: { observable: Ext.util.Observable }, useTopWindow: false, hashRe: /^(#?!?)/, constructor: function() { var me = this; me.ready = false; me.currentToken = null; me.mixins.observable.constructor.call(me); }, getHash: function() { return (this.win.location.hash || '').replace(this.hashRe, ''); }, setHash: function(hash, replace) { var me = this, hashRe = me.hashRe, loc = me.win.location; hash = hash.replace(hashRe, me.hashbang ? '#!' : '#'); try { if (replace) { loc.replace(hash); } else { loc.hash = hash; } me.currentToken = hash.replace(hashRe, ''); } catch (e) {} }, handleStateChange: function(token) { token = token.replace(this.hashRe, ''); this.fireEvent('change', this.currentToken = token); }, startUp: function() { var me = this; me.currentToken = me.getHash(); Ext.get(me.win).on('hashchange', me.onHashChange, 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; }, replace: function(token, preventDuplicates) { var me = this, set = false; if (preventDuplicates === false || me.getToken() !== token) { this.setHash(token, true); set = true; } return set; }, back: function() { this.win.history.go(-1); }, forward: function() { this.win.history.go(1); }, getToken: function() { return this.ready ? this.currentToken : this.getHash(); } }); Ext.define('Ext.route.Router', { singleton: true, config: { hashbang: null, multipleToken: '|', queueRoutes: true }, constructor: function() { var History = Ext.util.History; if (!History.ready) { History.init(); } History.on('change', this.onStateChange, this); this.initConfig(); this.clear(); }, updateHashbang: function(hashbang) { Ext.util.History.hashbang = hashbang; }, onStateChange: function(token) { var me = this, tokens = token.split(me.getMultipleToken()), queue, i, length; if (me.isSuspended) { queue = me.suspendedQueue; i = 0; length = tokens.length; if (queue) { for (; i < length; i++) { token = tokens[i]; if (!Ext.Array.contains(queue, token)) { queue.push(token); } } } } else { me.handleBefore(tokens); } }, handleBefore: function(tokens) { var me = this, action = new Ext.route.Action(); if (Ext.fireEvent('beforeroutes', action, tokens) === false) { action.destroy(); } else { action.run().then(me.handleBeforeRoute.bind(me, tokens), Ext.emptyFn); } }, handleBeforeRoute: function(tokens) { var me = this, beforeRoute = me.getByName('*'); if (beforeRoute) { beforeRoute.execute().then(me.doRun.bind(me, tokens), Ext.emptyFn); } else { me.doRun(tokens); } }, doRun: function(tokens) { var me = this, app = me.application, routes = me.routes, i = 0, length = tokens.length, matched = {}, unmatched = [], token, found, name, route, recognize; for (; i < length; i++) { token = tokens[i]; found = false; for (name in routes) { route = routes[name]; recognize = route.recognize(token); if (recognize) { found = true; if (recognize !== true) { route.execute(token, recognize).then(null, Ext.bind(me.onRouteRejection, me, [ route ], 0)); } Ext.Array.remove(unmatched, route); if (!matched[name]) { matched[name] = 1; } } else if (!matched[name]) { unmatched.push(route); } } if (!found) { if (app) { app.fireEvent('unmatchedroute', token); } Ext.fireEvent('unmatchedroute', token); } } i = 0; length = unmatched.length; for (; i < length; i++) { unmatched[i].onExit(); } }, onRouteRejection: function(route, error) { Ext.fireEvent('routereject', route, error); if (error) { Ext.raise(error); } }, connect: function(url, config, instance) { var routes = this.routes, delimiter = this.getMultipleToken(), name = config.name || url, handler, route; if (url[0] === '!') { if (!Ext.util.History.hashbang) { Ext.log({ level: 'error', msg: 'Route found with "!" ("' + url + '"). Should use new hashbang functionality instead. ' + 'Please see the router guide for more: https://docs.sencha.com/extjs/' + Ext.getVersion().version + '/guides/application_architecture/router.html' }); } url = url.substr(1); this.setHashbang(true); } if (Ext.isString(config)) { config = { action: config }; } handler = Ext.route.Handler.fromRouteConfig(config, instance); route = routes[name]; if (!route) { config.name = name; config.url = url; route = routes[name] = new Ext.route.Route(config); } route.addHandler(handler); if (handler.lazy) { var currentHash = Ext.util.History.getToken(), tokens = currentHash.split(delimiter), length = tokens.length, matched = [], i, token; for (i = 0; i < length; i++) { token = tokens[i]; if (Ext.Array.indexOf(matched, token) === -1 && route.recognize(token)) { matched.push(token); } } this.onStateChange(matched.join(delimiter)); } return handler; }, disconnect: function(instance, config) { var routes = this.routes, route, name; if (config) { route = config.route || this.getByName(config.name || config.url); if (route) { route.removeHandler(instance, config); } } else { for (name in routes) { route = routes[name]; route.removeHandler(instance); } } }, recognize: function(url) { var routes = this.routes, matches = [], name, arr, i, length, route, urlParams; for (name in routes) { arr = routes[name]; length = arr && arr.length; if (length) { i = 0; for (; i < length; i++) { route = arr[i]; urlParams = route.recognize(url); if (urlParams) { matches.push({ route: route, urlParams: urlParams }); } } } } return matches.length ? matches : false; }, draw: function(fn) { fn.call(this, this); }, clear: function() { this.routes = {}; }, clearLastTokens: function(token) { var routes = this.routes, name, route; for (name in routes) { route = routes[name]; if (!token || route.recognize(token)) { route.clearLastTokens(); } } }, getByName: function(name) { var routes = this.routes; if (routes) { return routes[name]; } }, suspend: function(trackTokens) { this.isSuspended = true; if (!this.suspendedQueue && trackTokens !== false) { this.suspendedQueue = []; } }, resume: function(discardQueue) { var me = this, queue = me.suspendedQueue, token; if (me.isSuspended) { me.isSuspended = false; me.suspendedQueue = null; if (!discardQueue && queue) { token = queue.join(me.getMultipleToken()); me.onStateChange(token); } } } }); Ext.define('Ext.route.Mixin', { extend: Ext.Mixin, mixinConfig: { id: 'routerable', before: { destroy: 'destroyRouterable' } }, config: { routes: null }, destroyRouterable: function() { Ext.route.Router.disconnect(this); }, applyRoutes: function(routes, oldRoutes) { var Router = Ext.route.Router, url; if (routes) { for (url in routes) { routes[url] = Router.connect(url, routes[url], this); } } if (oldRoutes) { for (url in oldRoutes) { Router.disconnect(this, oldRoutes[url]); } } return routes; }, redirectTo: function(hash, opt) { var me = this, currentHash = Ext.util.History.getToken(), Router = Ext.route.Router, delimiter = Router.getMultipleToken(), tokens = currentHash ? currentHash.split(delimiter) : [], length = tokens.length, force, i, name, obj, route, token, match; if (hash === -1) { return Ext.util.History.back(); } else if (hash === 1) { return Ext.util.History.forward(); } else if (hash.isModel) { hash = hash.toUrl(); } else if (Ext.isObject(hash)) { for (name in hash) { obj = hash[name]; if (!Ext.isObject(obj)) { obj = { token: obj }; } if (length) { route = Router.getByName(name); if (route) { match = false; for (i = 0; i < length; i++) { token = tokens[i]; if (route.matcherRegex.test(token)) { match = true; if (obj.token) { if (obj.fn && obj.fn.call(this, token, tokens, obj) === false) { continue; } tokens[i] = obj.token; if (obj.force) { route.lastToken = null; } } else { tokens.splice(i, 1); i--; length--; route.lastToken = null; } } } if (obj && obj.token && !match) { tokens.push(obj.token); } } } else if (obj && obj.token) { tokens.push(obj.token); } } hash = tokens.join(delimiter); } if (opt === true) { force = opt; opt = null; } else if (opt) { force = opt.force; } length = tokens.length; if (force && length) { for (i = 0; i < length; i++) { token = tokens[i]; Router.clearLastTokens(token); } } if (currentHash === hash) { if (force) { Router.onStateChange(hash); } return false; } if (opt && opt.replace) { Ext.util.History.replace(hash); } else { Ext.util.History.add(hash); } return true; }, privates: { afterClassMixedIn: function(targetClass) { var proto = targetClass.prototype, routes = proto.routes; if (routes) { delete proto.routes; targetClass.getConfigurator().add({ routes: routes }); } } } }); Ext.define('Ext.app.BaseController', { mixins: [ Ext.mixin.Observable, Ext.route.Mixin ], isController: true, config: { id: undefined, control: null, listen: 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); }, updateId: function(id) { this.id = id; }, 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.getId(); if (control) { this.control(control); } }, updateListen: function(listen) { this.getId(); if (listen) { this.listen(listen); } }, 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; if (bus) { bus.unlisten(me); me.eventbus = null; } me.callParent(); } }); 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; }, setupPaths: function(appName, appFolder, paths) { var manifestPaths = Ext.manifest, ns; if (appName && appFolder !== null) { manifestPaths = manifestPaths && manifestPaths.paths; if (!manifestPaths || appFolder !== undefined) { Ext.Loader.setPath(appName, (appFolder === undefined) ? 'app' : appFolder); } } if (paths) { for (ns in paths) { if (paths.hasOwnProperty(ns)) { Ext.Loader.setPath(ns, paths[ns]); } } } } }); Ext.getNamespace = Ext.app.getNamespace; }); 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, generation: 0, 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; }; }, isEqual: function(filter1, filter2) { if (filter1.getProperty() !== filter2.getProperty()) { return false; } if (filter1.getOperator() !== filter2.getOperator()) { return false; } if (filter1.getValue() === filter2.getValue()) { return true; } else if (Ext.isArray(filter1) && Ext.isArray(filter2) && Ext.Array.equals(filter1, filter2)) { return true; } return false; }, 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, notin: 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; me.generatedFilterFn = true; } 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(), serialized; delete result.id; delete result.serializer; if (serializer) { serialized = serializer.call(this, result); if (serialized) { result = serialized; } } return result; }, updateDisabled: function() { this.generation++; }, updateOperator: function() { this.onConfigMutation(); }, updateConvert: function() { this.onConfigMutation(); }, updateProperty: function() { this.onConfigMutation(); }, updateAnyMatch: function() { this.onConfigMutation(); }, updateExactMatch: function() { this.onConfigMutation(); }, updateCaseSensitive: function() { this.onConfigMutation(); }, updateValue: function(value) { this.onConfigMutation(); if (this.getDisableOnEmpty()) { this.setDisabled(Ext.isEmpty(value)); } }, updateFilterFn: function(filterFn) { delete this.generatedFilterFn; }, onConfigMutation: function() { this.generation++; if (this.generatedFilterFn) { this._filterFn = null; } }, updateDisableOnEmpty: function(disableOnEmpty) { if (disableOnEmpty) { this.setDisabled(Ext.isEmpty(this.getValue())); } }, 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)); }, notin: 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; }, "/=": function(candidate) { var me = this, v = me._filterValue; candidate = me.getCandidateValue(candidate, v); if (v !== me.lastRegExpSource) { me.lastRegExpSource = v; try { me.regex = new RegExp(v, 'i'); } catch (e) { me.regex = null; } } return me.regex ? me.regex.test(candidate) : false; } }); operatorFns['=='] = operatorFns['=']; operatorFns.gt = operatorFns['>']; operatorFns.ge = operatorFns['>=']; operatorFns.lt = operatorFns['<']; operatorFns.le = operatorFns['<=']; operatorFns.eq = operatorFns['=']; operatorFns.ne = operatorFns['!=']; }); Ext.define('Ext.util.AbstractMixedCollection', { 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); }, destroy: function() { var me = this; me.items = me.map = me.keys = me.indexMap = null; me.callParent(); }, 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(item) { return item.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; }, 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(); }, 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; }, 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.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() { var me = this, result = { root: me.getRoot(), property: me.getProperty(), direction: me.getDirection() }; if (me._id) { result.id = me._id; } return result; }, 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", 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(sorters[i], 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.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 item.$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) { this.callParent([ mapping ]); this.fireEvent('sort', this); }, 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.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.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.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, oldCollection) { if (collection) { collection.addObserver(this); } if (oldCollection) { oldCollection.removeObserver(this); } }, clone: function() { return new Ext.util.CollectionKey(this.getCurrentConfig()); }, destroy: function() { this.clear(); this.getCollection().removeObserver(this); this.destroyed = true; } }); 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.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 ], isCollection: true, config: { autoFilter: true, autoSort: true, autoGroup: true, decoder: null, extraKeys: null, filters: null, grouper: null, groups: null, groupConfig: null, rootProperty: null, sorters: null, multiSortLimit: 3, defaultSortDirection: 'ASC', source: null, trackGroups: true }, generation: 0, indices: null, indexRebuilds: 0, updating: 0, grouped: false, sorted: false, filtered: false, $endUpdatePriority: 1001, manageSorters: true, constructor: function(config) { var me = this; me.callParent([ config ]); 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) { me.grouped = me.sorted = false; me.setSorters(null); if (me.manageSorters) { sorters.destroy(); } } if (groups) { groups.destroy(); me._groups = null; } me.setSource(null); me.observers = me.items = me.map = null; me.callParent(); }, add: function(item) { var me = this, items = me.decodeItems(arguments, 0), ret = items; if (items.length) { me.splice(me.length, 0, items); ret = (items.length === 1) ? items[0] : items; } return ret; }, replaceAll: function() { var me = this, ret, items; 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.length = 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; }, containsAll: function(items) { var all = Ext.isArray(items) ? items : arguments, i; for (i = all.length; i-- > 0; ) { if (!this.contains(all[i])) { return false; } } return true; }, 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.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.splice(index, 0, items); ret = (items.length === 1) ? items[0] : items; } return ret; }, itemChanged: function(item, modified, oldKey, meta) { var me = this, keyChanged = oldKey !== undefined, 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(), toRemove = 0, itemFiltered = false, wasFiltered = false, details, newKey, sortFn, toAdd, index, newIndex; if (source && !source.updating) { me.sourceUpdating = true; source.itemChanged(item, modified, oldKey, meta); me.sourceUpdating = false; } 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 !== -1) { 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.generation; me.beginUpdate(); me.notify('beforeitemchange', [ details ]); if (keyChanged) { me.updateKey(item, oldKey, details); } 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; } me.requestedIndex = index; source.splice(i, removeItems, newItems); delete me.requestedIndex; 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 - 1) { --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(), index); } } if (insertAt === length) { end = insertAt; for (i = addItems.length - 1; i >= 0; --i) { items[end + i] = addItems[i]; } 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, details) { 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', [ Ext.apply({ item: item, newKey: newKey, oldKey: oldKey }, details) ]); me.updating--; } else { if (newKey in map && map[newKey] !== item) { Ext.raise('Duplicate newKey "' + newKey + '" for item with oldKey "' + oldKey + '"'); } if (oldKey in map && map[oldKey] !== item) { Ext.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; if (!this.sourceUpdating) { this.notify('beforeitemchange', [ details ]); } }, 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: function() { delete this.onCollectionUpdateKey; }, onCollectionRefresh: function(source) { var me = this, map = {}, indices = {}, items = me.items, sourceItems = source.items, filterFn = me.getFilterFn(), i, item, key, length, newLength; if (me.filtered && me.getAutoFilter()) { for (i = 0 , newLength = 0 , length = sourceItems.length; i < length; i++) { if (filterFn(sourceItems[i])) { items[newLength++] = sourceItems[i]; } } items.length = newLength; } else { items.length = 0; items.push.apply(items, sourceItems); } if (me.sorted) { me.sortData(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.generation; me.notify('refresh'); }, onCollectionRemove: function(source, details) { this.splice(0, details.items); }, onCollectionUpdateKey: function(source, details) { this.updateKey(details.item, details.oldKey, details); }, _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'); } if (me.notifying) { me.observers = observers = observers.slice(0); } 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) { me.notifying = true; 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); } } me.notifying = false; } 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.destroyed) { return; } if (source.length || me.length) { me.onCollectionRefresh(source); } } me.notify('filter'); }, applyFilters: function(filters, collection) { if (!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.getFilterCount() > 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.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, index) { return Ext.Array.findInsertionIndex(item, items || this.items, comparatorFn || this.getSortFn(), index); }, applySorters: function(sorters, collection) { if (!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 (me.getTrackGroups()) { if (!groups) { groups = new Ext.util.GroupCollection({ itemRoot: me.getRootProperty(), groupConfig: me.getGroupConfig() }); 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.destroyed) { oldSorters.un('endupdate', 'onEndUpdateSorters', me); } if (newSorters) { newSorters.on({ endupdate: 'onEndUpdateSorters', scope: me, priority: me.$endUpdatePriority }); if (me.manageSorters) { 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) { if (!oldSource.destroyed) { 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.data.Range', { isDataRange: true, begin: 0, buffer: 0, end: 0, length: 0, store: null, constructor: function(config) { var me = this, activeRanges, store; Ext.apply(me, config); store = me.store; if (!(activeRanges = store.activeRanges)) { store.activeRanges = activeRanges = []; } activeRanges.push(me); me.refresh(); if ('begin' in config) { me.begin = me.end = 0; me.goto(config.begin, config.end); } }, destroy: function() { var me = this, store = me.store, activeRanges = store && store.activeRanges; Ext.destroy(me.storeListeners); if (activeRanges) { Ext.Array.remove(activeRanges, me); } me.callParent(); }, "goto": function(begin, end) { var me = this, buffer = me.buffer, task = me.task; me.begin = begin; me.end = end; me.length = end - begin; if (buffer > 0) { if (!task) { me.task = task = new Ext.util.DelayedTask(me.doGoto, me); } task.delay(buffer); } else { me.doGoto(); } }, privates: { lastBegin: 0, lastEnd: 0, doGoto: Ext.privateFn, refresh: function() { this.records = this.store.getData().items; } } }); Ext.define('Ext.util.ObjectTemplate', { isObjectTemplate: true, excludeProperties: {}, valueRe: /^[{][a-z\.]+[}]$/i, statics: { create: function(template, options) { if (!Ext.isObject(template)) { Ext.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) { extra = Ext.apply({}, 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.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); } }, $roleFilterId: '$associationRoleFilter', 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 = { asynchronousLoad: false, model: me.cls, role: me, session: session, associatedEntity: from, disableMetaChangeEvent: true, pageSize: null, remoteFilter: true, trackRemoved: !session }, store; if (isMany) { config.filters = [ { id: me.$roleFilterId, property: me.inverse.field, value: id, exactMatch: true } ]; } else if (foreignKeyName) { config.filters = [ { id: me.$roleFilterId, 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 (!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, allowInfer) { var me = this, storeName = me.getStoreName(), store = inverseRecord[storeName], hadStore = store, session = inverseRecord.session, load = options && options.reload, source = inverseRecord.$source, isComplete = false, phantom = false, hadSourceStore, args, i, len, raw, rec, sourceStore, hadRecords, isLoading; if (!store) { if (session) { if (source) { phantom = source.phantom; } if (!records && source) { sourceStore = source[storeName]; if (sourceStore && !sourceStore.isLoading()) { records = []; raw = sourceStore.getData().items; for (i = 0 , len = raw.length; i < len; ++i) { rec = raw[i]; records.push(session.getRecord(rec.self, rec.id)); } isComplete = !!sourceStore.complete; hadSourceStore = true; } } if (!hadSourceStore) { hadRecords = !!records; records = me.findRecords(session, inverseRecord, records, allowInfer); if (!hadRecords && (!records || !records.length)) { records = null; } isComplete = phantom || hadRecords; } } else { isComplete = !!records; } store = me.createAssociationStore(session, inverseRecord, records, isComplete || inverseRecord.phantom); 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); } } isLoading = store.isLoading(); if (load) { if (!isLoading) { store.load(); } } else if (hadStore && records && !isLoading) { store.loadData(records); } return store; }, getAssociatedItem: function(rec) { var key = this.isMany ? this.getStoreName() : this.getInstanceName(); return rec[key] || null; }, onDrop: Ext.emptyFn, onIdChanged: 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; rightRecord = null; } } 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]; leftRecord.onAssociatedRecordSet(rightRecord, me); if (inverseSetter) { rightRecord[inverseSetter](leftRecord); } } } else { if (!foreignKey) { Ext.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', { 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; } }, onIdChanged: function(rightRecord, oldId, newId) { var leftRecord = this.getAssociatedItem(rightRecord), fieldName = this.association.getFieldName(); if (!rightRecord.session && leftRecord && fieldName) { leftRecord.set(fieldName, newId); } }, 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); } rightRecord.onAssociatedRecordSet(leftRecord, this); } 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 && field) { 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; if (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(); } } } }, onIdChanged: function(rightRecord, oldId, newId) { var fieldName = this.association.getFieldName(), store = this.getAssociatedItem(rightRecord), leftRecords, i, len, filter; if (store) { filter = store.getFilters().get(this.$roleFilterId); if (filter) { filter.setValue(newId); } if (!rightRecord.session && fieldName) { leftRecords = store.getDataSource().items; for (i = 0 , len = leftRecords.length; i < len; ++i) { leftRecords[i].set(fieldName, newId); } } } }, 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, leftRecord, id, i, len, seen; if (field && (refs || allowInfer)) { fieldName = field.name; ret = []; 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, true); } 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) { return me.getAssociatedStore(this, options, scope, leftRecords, true); }; }, createSetter: null, onAddToMany: function(store, leftRecords) { var rightRecord = store.getAssociatedEntity(); if (this.association.field) { this.syncFK(leftRecords, rightRecord, false); } else { this.setInstances(rightRecord, leftRecords); } }, onLoadMany: function(rightRecord, leftRecords, session) { this.setInstances(rightRecord, leftRecords, session); }, onRemoveFromMany: function(store, leftRecords) { if (this.association.field) { this.syncFK(leftRecords, store.getAssociatedEntity(), true); } else { this.setInstances(null, leftRecords); } }, 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; } } }, setInstances: function(rightRecord, leftRecords, session) { var instanceName = this.inverse.getInstanceName(), id = rightRecord ? rightRecord.getId() : null, field = this.association.field, len = leftRecords.length, i, leftRecord, oldId, data, name; for (i = 0; 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); } } } } }, 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; if (field) { 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, 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 = joined.length - 1; i >= 0; 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; }, onIdChanged: function(rightRecord, oldId, newId) { var store = this.getAssociatedItem(rightRecord); if (store) { store.getFilters().get(this.$roleFilterId).setValue(newId); } }, 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) { return me.getAssociatedStore(this, options, scope, leftRecords, false); }; }, 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 ], 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 ], alias: 'schema.default', aliasPrefix: 'schema.', isSchema: true, type: 'default', statics: { instances: {}, clearInstance: function(id) { var schema = this.instances[id]; delete this.instances[id]; if (schema) { schema.clear(true); schema.destroy(); } }, 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.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.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.raise('Ambiguous entity name "' + entity + '". Defined by schema "' + ret.schema.type + '" and "' + name + '"'); } ret = match; } } } if (!ret) { Ext.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, dupeCheck) { var me = this, namer = me.getNamer(), entities = me.entities, associations = me.associations, entityName = entityType.entityName, association = descr.association, 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 (!referenceField || descr.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 (dupeCheck && association in associations) { if (dupeCheck(associations[association], association, leftRole, rightRole) !== false) { return; } } if (association in associations) { Ext.raise('Duplicate association: "' + association + '" declared by ' + entityName + (referenceField ? ('.' + referenceField.name) : '') + ' (collides with ' + associations[association].definedBy.entityName + ')'); } if (referenceField && referenceField.definedBy === entities[rightType]) { Ext.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, left: { cls: entityType, type: entityName, role: leftRole, extra: left }, right: { cls: entry.cls, type: rightType, role: rightRole, extra: descr }, meta: 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.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.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); } me.addReference(entityType, referenceField, descr, referenceField.unique); }, addBelongsTo: function(entityType, assoc) { this.addKeylessSingle(entityType, assoc, false); }, addHasOne: function(entityType, assoc) { this.addKeylessSingle(entityType, assoc, true); }, addKeylessSingle: function(entityType, assoc, unique) { var foreignKey, referenceField; assoc = Ext.apply({}, this.checkLegacyAssociation(entityType, assoc)); assoc.type = this.getEntityName(assoc.child || assoc.parent || assoc.type); foreignKey = assoc.foreignKey || (assoc.type.toLowerCase() + '_id'); referenceField = entityType.getField(foreignKey); assoc.fromSingle = true; if (referenceField) { referenceField.$reference = assoc; referenceField.unique = true; assoc.legacy = true; Ext.log.warn('Using foreignKey is deprecated, use a keyed association. See Ext.data.field.Field.reference'); } this.addReference(entityType, referenceField, assoc, unique); }, addHasMany: function(entityType, assoc) { var me = this, entities = me.entities, pending = me.pending, cls, name, referenceField, target, foreignKey, inverseOptions, child, declaredInverse; assoc = Ext.apply({}, this.checkLegacyAssociation(entityType, assoc)); assoc.type = this.getEntityName(assoc.child || assoc.parent || assoc.type); name = assoc.type; target = entities[name]; cls = target && target.cls; if (cls) { name = entityType.entityName; foreignKey = assoc.foreignKey || (name.toLowerCase() + '_id'); delete assoc.foreignKey; declaredInverse = Ext.apply({}, assoc.inverse); delete assoc.inverse; inverseOptions = Ext.apply({}, assoc); delete inverseOptions.type; assoc = Ext.apply({ type: name, inverse: inverseOptions }, declaredInverse); child = inverseOptions.child; if (child) { delete inverseOptions.child; assoc.parent = name; } referenceField = cls.getField(foreignKey); if (referenceField) { referenceField.$reference = assoc; assoc.legacy = true; Ext.log.warn('Using foreignKey is deprecated, use a keyed association. See Ext.data.field.Field.reference'); } me.addReference(cls, referenceField, assoc, false, function(association, name, leftRole, rightRole) { var result = !!association.meta.fromSingle && cls === association.left.cls, l, r; if (result) { l = cls.entityName; r = entityType.entityName; Ext.raise('hasMany ("' + r + '") and belongsTo ("' + l + '") should not be used in conjunction to declare a relationship. Use only one.'); } return result; }); } else { if (!pending[name]) { pending[name] = []; } pending[name].push([ entityType, assoc ]); } }, checkLegacyAssociation: function(entityType, assoc) { if (Ext.isString(assoc)) { assoc = { type: assoc }; } else { assoc = Ext.apply({}, assoc); } if (assoc.model) { assoc.type = assoc.model; delete assoc.model; } var name = assoc.associatedName || assoc.name; if (name) { delete assoc.associatedName; delete assoc.name; assoc.role = name; } return assoc; }, afterKeylessAssociations: 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.addHasMany.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.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.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 ], 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, autoSort: null, reloadOnClearSorters: false }, currentPage: 1, loading: false, isStore: true, updating: 0, constructor: function(config) { var me = this, storeId; me.callParent([ config ]); 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); } }, createActiveRange: function(config) { var range = Ext.apply({ store: this }, config); return new Ext.data.Range(range); }, syncActiveRanges: function() { var activeRanges = this.activeRanges, len = activeRanges && activeRanges.length, i; for (i = 0; i < len; i++) { activeRanges[i].refresh(); } }, getCount: function() { var data = this.getData(); return data ? data.getCount() : 0; }, 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(fieldName, value, startIndex) { return this.getData().findIndexBy(function(rec) { return rec.isEqual(rec.get(fieldName), value); }, this, startIndex); }, 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, suppressEvent) { if (Ext.isString(filters)) { filters = { property: filters, value: value }; } this.suppressNextFilter = !!suppressEvent; this.getFilters().add(filters); this.suppressNextFilter = false; }, removeFilter: function(toRemove, suppressEvent) { var me = this, filters = me.getFilters(); me.suppressNextFilter = !!suppressEvent; if (toRemove instanceof Ext.util.Filter) { filters.remove(toRemove); } else { filters.removeByKey(toRemove); } me.suppressNextFilter = false; }, updateAutoSort: function(autoSort) { this.getData().setAutoSort(autoSort); }, updateRemoteSort: function(remoteSort) { this.onRemoteSortSet(this.getSorters(false), remoteSort); }, updateRemoteFilter: function(remoteFilter) { this.onRemoteFilterSet(this.getFilters(false), remoteFilter); }, addFilter: function(filters, suppressEvent) { this.suppressNextFilter = !!suppressEvent; this.getFilters().add(filters); this.suppressNextFilter = false; }, filterBy: function(fn, scope) { this.getFilters().add({ filterFn: fn, scope: scope || this }); }, clearFilter: function(suppressEvent) { var me = this, filters = me.getFilters(false); if (!filters || filters.getCount() === 0) { return; } me.suppressNextFilter = !!suppressEvent; 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.hasListeners.beginupdate) { this.fireEvent('beginupdate'); } }, endUpdate: function() { if (this.updating && !--this.updating) { if (this.hasListeners.endupdate) { 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) { me.setGrouper(stateGrouper); } }, hasPendingLoad: Ext.emptyFn, isLoaded: Ext.emptyFn, isLoading: Ext.emptyFn, destroy: function() { var me = this; if (me.hasListeners.beforedestroy) { me.fireEvent('beforedestroy', me); } me.destroying = true; if (me.getStoreId()) { Ext.data.StoreManager.unregister(me); } me.doDestroy(); if (me.hasListeners.destroy) { me.fireEvent('destroy', me); } me.destroying = false; me.callParent(); }, doDestroy: Ext.emptyFn, sort: function(field, direction, mode) { var me = this; if (arguments.length === 0) { if (me.getRemoteSort()) { me.load(); } 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, fireSort = true, sorters = me.getSorters(false), sorterCount; if (me.settingGroups || !sorters) { return; } sorters = sorters.getRange(); sorterCount = sorters.length; if (me.getRemoteSort()) { if (sorters.length || me.getReloadOnClearSorters()) { fireSort = false; me.load({ callback: function() { me.fireEvent('sort', me, sorters); } }); } } else if (sorterCount) { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); } if (fireSort) { me.fireEvent('sort', me, sorters); } }, onFilterEndUpdate: function() { var me = this, suppressNext = me.suppressNextFilter, filters = me.getFilters(false); if (!filters) { return; } if (me.getRemoteFilter()) { me.getFilters().each(function(filter) { if (filter.getInitialConfig().filterFn) { Ext.raise('Unable to use a filtering function in conjunction with remote filtering.'); } }); me.currentPage = 1; if (!suppressNext) { me.load(); } } 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), data = me.getData(); if (grouper && typeof grouper === 'string') { grouper = { property: grouper, direction: direction || me.getGroupDir() }; } me.settingGroups = true; if (grouper === data.getGrouper()) { data.updateGrouper(grouper); } else { data.setGrouper(grouper); } delete me.settingGroups; if (change) { if (me.getRemoteSort()) { if (!me.isInitializing) { me.load({ scope: me, callback: me.fireGroupChange }); } } else { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); me.fireGroupChange(); } } else { me.fireGroupChange(); } }, fireGroupChange: function() { if (!this.destroyed) { 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: { _metaProperties: { count: 'getCount', first: 'first', last: 'last', loading: 'hasPendingLoad', totalCount: 'getTotalCount' }, interpret: function(name) { var me = this, accessor = me._metaProperties[name]; return accessor && me[accessor](); }, loadsSynchronously: Ext.privateFn, onRemoteFilterSet: function(filters, remoteFilter) { if (filters) { filters[remoteFilter ? 'on' : 'un']('endupdate', 'onFilterEndUpdate', this); } }, onRemoteSortSet: function(sorters, remoteSort) { var me = this, data; if (sorters) { sorters[remoteSort ? 'on' : 'un']('endupdate', 'onSorterEndUpdate', me); data = me.getData(); if (data) { data[remoteSort ? 'un' : 'on']('beforesort', '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', 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, record); 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, request; delete me.error; delete me.success; me.complete = me.exception = false; me.setStarted(); me.request = request = me.doExecute(); if (request) { request.setOperation(me); } return request; }, doExecute: Ext.emptyFn, abort: function() { var me = this, request = me.request, proxy; me.aborted = true; if (me.running && request) { proxy = me.getProxy(); if (proxy && !proxy.destroyed) { proxy.abort(request); } me.request = null; } me.running = false; }, 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.complete = true; me.running = false; if (!me.destroying) { me.triggerCallbacks(); } if (me.destroyed) { return; } proxy = me.getProxy(); if (proxy && !proxy.destroyed) { 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); if (me.destroyed) { return; } me.setInternalCallback(null); me.setInternalScope(null); } if (callback = me.getCallback()) { callback.call(me.getScope() || me, me.getRecords(), me, me.wasSuccessful()); if (me.destroyed) { return; } 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; }, destroy: function() { var me = this; me.destroying = true; if (me.running) { me.abort(); } me._params = me._callback = me._scope = me._resultSet = me._response = null; me.request = me._request = me._records = me._proxy = me._batch = null; me._recordCreator = me._internalCallback = me._internalScope = null; me.callParent(); } }); 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', function() { var me; return { singleton: true, constructor: function() { me = this; }, none: Ext.identityFn, stripCommasRe: /,/g, stripTagsRE: /<\/?[^>]+>/gi, asText: function(s) { return (s != null) ? String(s).replace(me.stripTagsRE, '') : '\x00'; }, asUCText: function(s) { return (s != null) ? String(s).toUpperCase().replace(me.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(me.stripCommasRe, '')); return isNaN(val) ? 0 : val; }, asInt: function(s) { var val = parseInt(String(s).replace(me.stripCommasRe, ''), 10); return isNaN(val) ? 0 : val; } }; }); Ext.define('Ext.data.validator.Validator', { mixins: [ Ext.mixin.Factoryable ], alias: 'data.validator.base', isValidator: true, factoryConfig: { cacheable: true }, type: 'base', 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(Validator) { Ext.Factory.validator = Ext.Factory.dataValidator; }); Ext.define('Ext.data.field.Field', { mixins: [ Ext.mixin.Factoryable ], 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, summary: null, summaryField: '', 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 = Ext.Function.toCode(calculate); 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; }, constructValidators: function(validators) { if (validators) { if (!(validators instanceof Array)) { validators = [ validators ]; } var length = validators.length, all = this._validators, i, item, validator, presence; for (i = 0; i < length; ++i) { item = validators[i]; if (item.fn) { item = item.fn; } validator = Ext.Factory.dataValidator(item); if (!validator.isPresence) { all.push(validator); } else { presence = validator; } } if (presence) { this.presence = [ presence ]; } } }, 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, record) { var me = this, validators = me.getValidators(), result, presence; presence = this.presence; if (presence && (value == null || value === '')) { result = me.validateGroup(presence, value, separator, errors, record); if (result !== true) { return result; } } return me.validateGroup(validators, value, separator, errors, record); }, validateGroup: function(validators, value, separator, errors, record) { var ret = '', validator, length, i, result; for (i = 0 , length = validators.length; i < length; ++i) { validator = validators[i]; result = validator.validate(value, record); if (result !== true) { result = result || this.defaultInvalidMessage; if (errors) { if (errors.isMixedCollection) { errors.add(this.name, result); } else if (errors.isCollection) { errors.add(result); } else { errors.push(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; }, getSummary: function() { var me = this, doneSummary = me.doneSummary, summary = me.summary; if (!doneSummary) { me.doneSummary = true; if (summary) { me.summary = summary = Ext.Factory.dataSummary(summary); } } return summary || null; }, getType: function() { return 'auto'; }, privates: { getValidators: function() { var me = this, validators = me._validators; if (!validators) { me._validators = validators = []; me.constructValidators(me.validators); me.constructValidators(me.modelValidators); me.constructValidators(me.instanceValidators); } return validators; } }, 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, this.useStrict); } 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 == 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, id; me.initConfig(config); id = me.getId(); if (id) { Ext.data.identifier.Generator.all[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 && 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', isEntity: true, isModel: true, validIdRe: null, erasing: false, loadOperation: null, loadCount: 0, observableType: 'record', crudState: 'R', crudStateWas: null, 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.internalId = internalId = modelIdentifier.generate(); var dataId = data[idProperty]; if (session && !session.isSession) { Ext.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.isSummaryModel) { if (!(me.id = id = data[idProperty]) && id !== 0) { if (dataId) { Ext.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; me.crudState = 'C'; } if (session) { session.add(me); } if (me.phantom) { me.crudStateWas = 'C'; } } 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', summary: null, 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) }; } }, calculateSummary: function(records) { var fields = this.getFields(), len = fields.length, recLen = records.length, i, result, summary, prop, name, field; for (i = 0; i < len; ++i) { field = fields[i]; summary = field.getSummary(); if (summary) { result = result || {}; name = field.name; prop = field.summaryField || name; result[name] = summary.calculate(records, prop, 'data', 0, recLen); } } if (result) { this.set(result, this._commitOptions); } }, cancelEdit: function() { var me = this, editMemento = me.editMemento, validation = me.validation; if (editMemento) { me.editing = false; Ext.apply(me, editMemento); me.editMemento = null; if (validation && validation.syncGeneration !== me.generation) { validation.syncGeneration = 0; } } }, 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, options) { this.set(this.idProperty, id, options); }, 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, dirtyRank = 0, associations = me.associations, currentValue, field, idChanged, key, name, oldId, comparator, dep, dependents, i, numFields, newId, rankedFields, reference, value, values, roleName; 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.onIdChanged(newId, oldId); me.callJoined('onIdChanged', [ oldId, newId ]); if (associations) { for (roleName in associations) { associations[roleName].onIdChanged(me, 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.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(owner) { var me = this, joined = me.joined; if (!joined) { joined = me.joined = [ owner ]; } else if (!joined.length) { joined[0] = owner; } else { Ext.Array.include(joined, owner); } if (owner.isStore && !me.store) { me.store = owner; } }, unjoin: function(owner) { var me = this, joined = me.joined, len = joined && joined.length, store = me.store, i; if (owner === me.session) { me.session = null; } else { if (len === 1 && joined[0] === owner) { joined.length = 0; } else if (len) { Ext.Array.remove(joined, owner); } if (store === owner) { store = null; if (joined) { for (i = 0 , len = joined.length; i < len; ++i) { owner = joined[i]; if (owner.isStore) { store = owner; 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.apply({}, 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) { if (typeof associated === 'object') { me.getNestedData(opts, ret); } else { me.getAssociatedData(ret, opts); } } return ret; }, getNestedData: function(options, result) { var me = this, associations = me.associations, graph = options.associated, i, item, items, itemData, length, record, role, roleName, opts; result = result || {}; for (roleName in graph) { role = associations[roleName]; opts = graph[roleName]; if (opts === true) { delete options.associated; } else { options.associated = opts; } item = role.getAssociatedItem(me); if (item.isStore) { items = item.getData().items; length = items.length; itemData = []; for (i = 0; i < length; ++i) { record = items[i]; itemData.push(record.getData(options)); } } else { itemData = item.getData(options); } result[roleName] = itemData; } options.associated = graph; return result; }, 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.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; ++me.loadCount; 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; }, mergeData: function(data) { if (!this.dirty) { this.set(data, this._commitOptions); } }, 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; }, statics: { defaultProxy: 'memory' }, inheritableStatics: { _associatedReadOptions: { recordsOnly: true, asRoot: true }, loadData: function(data, session) { var rec; if (data) { rec = this.getProxy().getReader().readRecords([ data ], session ? { recordCreator: session.recordCreator } : undefined, this._associatedReadOptions)[0]; } else { rec = new this(data, session); } return rec; }, getSummaryModel: function() { var me = this, proto = me.prototype, summaryModel = me.summaryModel; if (!summaryModel) { summaryModel = Ext.define(null, { extend: me, fields: proto.summaryFields || [], isSummaryModel: true }); summaryModel.isSummaryModel = true; me.summaryModel = proto.summaryModel = summaryModel; } return summaryModel || null; }, 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, cleared; if (removeFields === true) { fields.length = 0; me.fieldsMap = fieldsMap = {}; me.fieldOrdinals = ordinals = {}; cleared = true; } 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; } } if (!cleared) { for (i = 0 , len = fields.length; i < len; ++i) { fields[i].rank = null; } } me.idField = proto.idField = idField = fieldsMap[proto.idProperty]; if (idField) { 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, defaultProxy = me.defaultProxy, defaults; if (!proxy) { proxy = me.proxyConfig; if (!proxy && defaultProxy) { proxy = defaultProxy; } if (!proxy || !proxy.isProxy) { if (typeof proxy === 'string') { proxy = { type: proxy }; } defaults = Ext.merge(me.schema.constructProxy(me), proxy); if (proxy && proxy.type) { proxy = proxy.schema === false ? proxy : defaults; } else { 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; if (session) { rec = session.peekRecord(this, id); } if (!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 }, _metaProperties: { dirty: 'isDirty', phantom: 'isPhantom', valid: 'isValid' }, 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, state = me.dropped ? 'D' : (me.phantom ? 'C' : (me.dirty ? 'U' : 'R')), i, len, fn, item; me.crudState = state; if (joined || session) { if (args) { args.unshift(me); } else { args = [ me ]; } fn = session && session[funcName]; if (fn) { fn.apply(session, args); } if (joined) { for (i = 0 , len = joined.length; i < len; ++i) { item = joined[i]; if (item && (fn = item[funcName])) { fn.apply(item, args); } } } } me.crudStateWas = state; }, hasPendingLoad: function() { return this.isLoading(); }, interpret: function(name) { var me = this, accessor = me._metaProperties[name]; if (!accessor) { accessor = me.associations; accessor = accessor && accessor[name] && accessor[name].getterName; } if (accessor) { return me[accessor](); } return me.data[name]; }, isDirty: function() { return this.dirty; }, isPhantom: function() { return this.phantom; }, onAssociatedRecordSet: function(record, role) { this.callJoined('afterAssociatedRecordSet', [ record, role ]); }, onIdChanged: Ext.privateFn, setSession: function(session) { if (session) { if (this.session) { Ext.raise('This model already belongs to a session.'); } if (!this.id) { Ext.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.isEqual(lhs, rhs); } } 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.raise(cls.$className + " has circular field dependencies: " + topoStack.join(" --> ")); } if (topoStack.length && field.evil) { Ext.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.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, superIdDeclared, 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; } } } delete data.fields; if (fieldDefs) { 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; } if (name === superIdFieldName) { superIdDeclared = true; } } } 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 && !superIdDeclared && 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; } }, initSummaries: function(data, cls, proto) { var summaryDefs = data.summary, superSummaries = proto.summaryFields, summaries, summaryMap, name, summary, len, i, index, field; if (superSummaries) { summaries = []; summaryMap = {}; for (i = 0 , len = superSummaries.length; i < len; ++i) { summary = superSummaries[i]; summaries.push(summary); summaries[summary.name] = i; } } if (summaryDefs) { delete data.summary; summaries = summaries || []; summaryMap = summaryMap || {}; for (name in summaryDefs) { summary = summaryDefs[name]; if (typeof summary === 'function') { summary = { summary: summary }; } index = summaryMap[name]; summary = Ext.apply({ name: name }, summary); field = summary.field; if (field) { delete summary.field; summary.summaryField = field; } if (index === undefined) { index = summaries.length; summaryMap[name] = summary; } summaries[index] = summary; } } if (summaries) { for (i = 0 , len = summaries.length; i < len; ++i) { if (summaries[i].name in proto.fieldsMap) { Ext.raise('Cannot redefine field, use the summary property on the field.'); } } proto.summaryFields = summaries; } }, 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 (validator) { 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, o; delete data.associations; delete data.belongsTo; delete data.hasMany; delete data.hasOne; delete data.manyToMany; if (matrices) { schema.addMatrices(cls, matrices); } if (associations) { associations = Ext.isArray(associations) ? associations : [ associations ]; for (i = 0 , length = associations.length; i < length; ++i) { assoc = associations[i]; o = Ext.apply({}, assoc); delete o.type; switch (assoc.type) { case 'belongsTo': schema.addBelongsTo(cls, o); break; case 'hasMany': schema.addHasMany(cls, o); break; case 'hasOne': schema.addHasOne(cls, o); break; default: Ext.raise('Invalid association type: "' + assoc.type + '"'); } } } if (belongsTo) { belongsTo = Ext.isArray(belongsTo) ? belongsTo : [ belongsTo ]; for (i = 0 , length = belongsTo.length; i < length; ++i) { schema.addBelongsTo(cls, belongsTo[i]); } } if (hasMany) { hasMany = Ext.isArray(hasMany) ? hasMany : [ hasMany ]; for (i = 0 , length = hasMany.length; i < length; ++i) { schema.addHasMany(cls, hasMany[i]); } } if (hasOne) { hasOne = Ext.isArray(hasOne) ? hasOne : [ hasOne ]; for (i = 0 , length = hasOne.length; i < length; ++i) { schema.addHasOne(cls, hasOne[i]); } } schema.afterKeylessAssociations(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' ], 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]; 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.raise('Anonymous entities cannot specify "associations"'); } if (data.belongsTo) { Ext.raise('Anonymous entities cannot specify "belongsTo"'); } if (data.hasMany) { Ext.raise('Anonymous entities cannot specify "hasMany"'); } if (data.hasOne) { Ext.raise('Anonymous entities cannot specify "hasOne"'); } if (data.matrices) { Ext.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); if (!data.isSummaryModel) { Model.initSummaries(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, remoteTotal: null, success: false, records: null, message: null, metadata: null, groupData: null, summaryData: 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' ], mixins: [ Ext.mixin.Observable, Ext.mixin.Factoryable ], alias: 'reader.base', factoryConfig: { defaultType: null }, config: { groupRootProperty: '', implicitIncludes: true, keepRawData: null, messageProperty: '', model: null, proxy: null, readRecordsOnFailure: true, rootProperty: '', successProperty: 'success', summaryRootProperty: '', totalProperty: 'total', transform: null, typeProperty: '' }, 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(); }, forceBuildExtractors: function() { if (!this.duringInit) { this.buildExtractors(true); } }, updateGroupRootProperty: function() { this.forceBuildExtractors(); }, updateMessageProperty: function() { this.forceBuildExtractors(); }, applyModel: function(model) { return Ext.data.schema.Schema.lookupEntity(model); }, updateSuccessProperty: function() { this.forceBuildExtractors(); }, updateTotalProperty: function() { this.forceBuildExtractors(); }, applyTransform: function(transform) { if (transform) { if (Ext.isFunction(transform)) { transform = { fn: transform }; } else if (transform.charAt) { transform = { fn: this[transform] }; } return transform.fn.bind(transform.scope || this); } return transform; }, read: function(response, readOptions) { var data, result, responseText; if (response) { responseText = response.responseText; if (response.responseType || 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 if (responseText !== '') { 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, groupData = null, summaryData = null, success, recordCount, records, root, remoteTotal, total, value, message, transform, meta, summaryOptions; meta = me.getMeta ? me.getMeta(data) : data.metaData; if (meta) { me.onMetaChange(meta); } transform = me.getTransform(); if (transform) { data = transform(data); } me.buildExtractors(); if (me.getKeepRawData()) { me.rawData = data; } if (me.hasListeners.rawdata) { me.fireEventArgs('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)) { remoteTotal = total = value; } } if (root) { records = me.extractData(root, readOptions); recordCount = records.length; } if (me.getGroupRootProperty()) { root = me.getGroupRoot(data); if (root) { summaryOptions = { includes: false, model: me.getModel().getSummaryModel() }; groupData = me.extractData(root, summaryOptions) || null; } } if (me.getSummaryRootProperty()) { root = me.getSummaryRoot(data); if (root) { summaryOptions = summaryOptions || { includes: false, model: me.getModel().getSummaryModel() }; summaryData = me.extractData(root, summaryOptions) || null; if (summaryData) { summaryData = summaryData[0]; } } } } return recordsOnly ? records : new Ext.data.ResultSet({ total: total || recordCount, remoteTotal: remoteTotal, metadata: meta, count: recordCount, records: records, success: success, message: message, groupData: groupData, summaryData: summaryData }); }, extractData: function(root, readOptions) { var me = this, entityType = readOptions && readOptions.model ? Ext.data.schema.Schema.lookupEntity(readOptions.model) : me.getModel(), schema = entityType.schema, includes = readOptions && 'includes' in readOptions ? readOptions.includes : schema.hasAssociations(entityType) && me.getImplicitIncludes(), fieldExtractorInfo = me.getFieldExtractorInfo(entityType), 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)); } 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); 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(entityType) { var extractors = entityType.fieldExtractors, type, extractor; if (!extractors) { return; } type = this.$className; extractor = extractors[type]; if (extractor === undefined) { extractors[type] = extractor = this.buildFieldExtractors(entityType); } return extractor; }, buildFieldExtractors: function(entityType) { var fields = entityType.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, self); if (val !== undefined) { data[\'' + name + '\'] = val; }'); extractors.push(extractor); ++cnt; } } if (buffer.length) { out = { extractors: extractors, fn: new Function('raw', 'data', 'extractors', 'self', 'var val;' + buffer.join('\n')) }; } return out; }, defaultRecordCreator: function(data, Model) { return new Model(data); }, defaultRecordCreatorFromServer: 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, this); } 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); } } } }, getData: Ext.identityFn, getRoot: Ext.identityFn, getResponseData: function(response) { Ext.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); if (key) { ret = cache.get(key); } if (!ret) { ret = me.createAccessor(prop); if (key) { cache.add(key, ret); } } } else { ret = me.createAccessor(prop); } return ret; }, getAccessorKey: function(prop) { var className = this.$className; return className ? className + prop : ''; }, createAccessor: Ext.emptyFn, createFieldAccessor: Ext.emptyFn, destroy: function() { var me = this; me.model = me.getTotal = me.getSuccess = me.getMessage = me.rawData = null; me.onMetaChange = null; me.transform = null; me.callParent(); }, 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; }, getGroupRoot: Ext.privateFn, getSummaryRoot: Ext.privateFn } }, 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' ], 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) { if (this.isSynchronous) { reader = reader || {}; reader.keepRawData = true; } 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.responseType != null) { me.responseType = reader.responseType; } } }, 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), null, { single: true, priority: 1000 }); batch.$destroyOwner = options.$destroyOwner; 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 ]); } if (!batch.$destroyOwner) { batch.destroy(); } }, 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(); } op.destroy(); } this.pendingOperations = null; this.callParent(); } }); Ext.define('Ext.data.proxy.Client', { extend: Ext.data.proxy.Proxy, alternateClassName: 'Ext.data.ClientProxy', isSynchronous: true, clear: function() { Ext.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: null, data: { $value: null, merge: function(newValue, currentValue, target, mixinClass) { return newValue ? Ext.clone(newValue) : newValue; } }, clearOnRead: null }, finishOperation: function(operation) { var recs = operation.getRecords(), len = recs.length, i; for (i = 0; i < len; i++) { recs[i].dropped = !!operation.isDestroyOperation; 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, reader = me.getReader(), resultSet = reader.read(me.getData(), { recordCreator: reader.defaultRecordCreatorFromServer }), records = resultSet.getRecords(), sorters = operation.getSorters(), grouper = operation.getGrouper(), filters = operation.getFilters(), start = operation.getStart(), limit = operation.getLimit(), meta; if (operation.process(resultSet, null, null, false) !== false) { if (operation.success && me.getClearOnRead()) { this.setData(null); } 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(); if (meta = resultSet.getMetadata()) { me.onMetaChange(meta); } } }, clear: Ext.emptyFn }); Ext.define('Ext.data.ProxyStore', { extend: Ext.data.AbstractStore, config: { model: undefined, fields: null, proxy: undefined, autoLoad: undefined, autoSync: false, batchUpdateMode: 'operation', sortOnLoad: true, trackRemoved: true, asynchronousLoad: undefined }, 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: 'Ext.data.Model', autoSyncSuspended: 0, removed: null, constructor: function(config) { var me = this; var configModel = me.model; me.callParent(arguments); if (me.getAsynchronousLoad() === false) { me.flushLoad(); } 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('')); } }, doDestroy: function() { var me = this, proxy = me.getProxy(); me.clearLoadTask(); Ext.destroy(me.getData()); me.data = null; me.setProxy(null); if (proxy.autoCreated) { proxy.destroy(); } me.setModel(null); me.callParent(); }, applyAsynchronousLoad: function(asynchronousLoad) { if (asynchronousLoad == null) { asynchronousLoad = !this.loadsSynchronously(); } return asynchronousLoad; }, updateAutoLoad: function(autoLoad) { this.getData(); if (autoLoad) { this.load(Ext.isObject(autoLoad) ? autoLoad : undefined); } }, getTotalCount: function() { return this.totalCount || 0; }, applyFields: function(fields) { if (fields) { this.createImplicitModel(fields); } }, applyModel: function(model) { if (model) { model = Ext.data.schema.Schema.lookupEntity(model); } else if (!this.destroying) { this.getFields(); model = this.getModel() || this.createImplicitModel(); } 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(); this.useModelProxy = true; } if (!proxy) { proxy = Ext.createByAlias('proxy.memory'); proxy.autoCreated = true; } } return proxy; }, applyState: function(state) { var me = this; me.callParent([ state ]); if (me.getAutoLoad() || me.isLoaded()) { me.load(); } }, 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; if (batch.$destroyOwner === me) { batch.destroy(); } me.fireEvent('datachanged', me); }, onBatchException: function(batch, operation) {}, filterNew: function(item) { return item.phantom && item.isValid(); }, getNewRecords: function() { return []; }, getUpdatedRecords: function() { return []; }, getModifiedRecords: function() { return [].concat(this.getNewRecords(), this.getUpdatedRecords()); }, filterUpdated: function(item) { return item.dirty && !item.phantom && item.isValid(); }, getRemovedRecords: function() { var removed = this.getRawRemovedRecords(); return removed ? Ext.Array.clone(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(), $destroyOwner: me })); } 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) { var me = this; if (typeof options === 'function') { options = { callback: options }; } else { options = options ? Ext.Object.chain(options) : {}; } me.pendingLoadOptions = options; if (me.getAsynchronousLoad()) { if (!me.loadTimer) { me.loadTimer = Ext.asap(me.flushLoad, me); } } else { me.flushLoad(); } return me; }, flushLoad: function() { var me = this, options = me.pendingLoadOptions, operation; if (me.destroying || me.destroyed) { return; } me.clearLoadTask(); if (!options) { return; } me.setLoadOptions(options); if (me.getRemoteSort() && options.sorters) { me.fireEvent('beforesort', me, options.sorters); } operation = Ext.apply({ internalScope: me, internalCallback: me.onProxyLoad, scope: me }, options); me.lastOptions = operation; operation = me.createOperation('read', operation); if (me.fireEvent('beforeload', me, operation) !== false) { me.onBeforeLoad(operation); me.loading = true; if (me.hasListeners.beginload) { me.fireEvent('beginload', me, operation); } operation.execute(); } }, reload: function(options) { return this.load(Ext.apply({}, options, this.lastOptions)); }, 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); me.fireEvent('datachanged', me); } }, 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); me.fireEvent('datachanged', me); } }, afterErase: function(record) { this.onErase(record); }, onErase: Ext.emptyFn, onUpdate: Ext.emptyFn, hasPendingLoad: function() { return !!this.pendingLoadOptions || 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: { getRawRemovedRecords: function() { return this.removed; }, onExtraParamsChanged: function() {}, clearLoadTask: function() { this.pendingLoadOptions = this.loadTimer = Ext.unasap(this.loadTimer); }, cleanRemoved: function() { var removed = this.getRawRemovedRecords(), 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); }, createImplicitModel: function(fields) { var me = this, modelCfg = { extend: me.implicitModel, statics: { defaultProxy: 'memory' } }, proxy, model; if (fields) { modelCfg.fields = fields; } model = Ext.define(null, modelCfg); me.setModel(model); proxy = me.getProxy(); if (proxy) { model.setProxy(proxy); } else { me.setProxy(model.getProxy()); } }, loadsSynchronously: function() { return this.getProxy().isSynchronous; }, onBeforeLoad: Ext.privateFn, removeFromRemoved: function(record) { var removed = this.getRawRemovedRecords(); if (removed) { Ext.Array.remove(removed, record); record.unjoin(this); } }, setLoadOptions: function(options) { var me = this, filters, sorters; if (me.getRemoteFilter()) { filters = me.getFilters(false); if (filters && filters.getCount()) { options.filters = filters.getRange(); } } if (me.getRemoteSort()) { sorters = me.getSorters(false); if (sorters && sorters.getCount()) { options.sorters = sorters.getRange(); } } } } }); Ext.define('Ext.util.Group', { extend: Ext.util.Collection, config: { groupKey: null }, $endUpdatePriority: 2001, manageSorters: false }); Ext.define('Ext.data.Group', { extend: Ext.util.Group, store: null, getSummaryRecord: function() { var me = this, summaryRecord = me.summaryRecord, store = me.store, generation = store.getData().generation, M, T; if (!summaryRecord) { M = store.getModel(); T = M.getSummaryModel(); me.summaryRecord = summaryRecord = new T(); } if (!summaryRecord.isRemote && summaryRecord.summaryGeneration !== generation) { summaryRecord.calculateSummary(me.items); summaryRecord.summaryGeneration = generation; } return summaryRecord; } }); 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(record) { return this.insert(this.getCount(), arguments.length === 1 ? record : arguments); }, constructDataCollection: function() { var result = new Ext.util.Collection({ rootProperty: 'data', groupConfig: { xclass: 'Ext.data.Group', store: this } }); result.addObserver(this); return result; }, 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; }, getSummaryRecord: function() { var me = this, summaryRecord = me.summaryRecord, data = me.getData(), generation = data.generation, T; if (!summaryRecord) { T = me.getModel().getSummaryModel(); me.summaryRecord = summaryRecord = new T(); } if (!summaryRecord.isRemote && summaryRecord.summaryGeneration !== generation) { summaryRecord.calculateSummary(data.items); summaryRecord.summaryGeneration = generation; } return summaryRecord; }, onCollectionBeginUpdate: function() { this.beginUpdate(); }, onCollectionEndUpdate: function() { this.endUpdate(); }, onCollectionSort: function() { this.onSorterEndUpdate(); }, onCollectionFilter: function() { this.onFilterEndUpdate(); }, notifySorterChange: function() { this.getData().onSorterChange(); }, forceLocalSort: function() { var sorters = this.getSorters(); sorters.beginUpdate(); sorters.endUpdate(); }, contains: function(record) { return this.indexOf(record) > -1; }, each: function(fn, scope, includeOptions) { var data = this.getData(), bypassFilters = includeOptions, len, record, i; if (typeof includeOptions === 'object') { bypassFilters = includeOptions.filtered; } if (bypassFilters && data.filtered) { data = data.getSource(); } data = data.items.slice(0); len = data.length; for (i = 0; i < len; ++i) { record = data[i]; if (fn.call(scope || record, record, i, len) === false) { break; } } }, collect: function(property, includeOptions, filtered) { var me = this, allowNull = includeOptions, data = me.getData(); if (typeof includeOptions === 'object') { filtered = includeOptions.filtered; allowNull = includeOptions.allowNull; } if (filtered && data.filtered) { data = data.getSource(); } return data.collect(property, '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 (data.filtered) { if (!data.$hasExtraKeys) { keyCfg = this.makeInternalKeyCfg(); data.setExtraKeys(keyCfg); data.$hasExtraKeys = true; } data = data.getSource(); } if (!data.$hasExtraKeys) { data.setExtraKeys(keyCfg || this.makeInternalKeyCfg()); data.$hasExtraKeys = true; } return data.byInternalId.get(internalId) || null; }, getDataSource: function() { var data = this.getData(); return data.getSource() || data; }, 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(); }, makeInternalKeyCfg: function() { return { byInternalId: { property: 'internalId', rootProperty: '' } }; } } }); Ext.define('Ext.data.proxy.Server', { extend: Ext.data.proxy.Proxy, alias: 'proxy.server', alternateClassName: 'Ext.data.ServerProxy', 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: {} }, primitiveRe: /string|number|boolean/, 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) { var extraParams = this.getExtraParams(); extraParams[name] = value; this.fireEvent('extraparamschanged', extraParams); }, updateExtraParams: function(newExtraParams, oldExtraParams) { this.fireEvent('extraparamschanged', newExtraParams); }, 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, meta, destroyOp; if (me.destroying || me.destroyed) { return; } 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() || reader.defaultRecordCreatorFromServer }); } if (!operation.$destroyOwner) { operation.$destroyOwner = me; destroyOp = true; } operation.process(resultSet, request, response); exception = !operation.wasSuccessful(); } else { me.setException(operation, response); exception = true; } if (me.destroyed) { if (!operation.destroyed && destroyOp && operation.$destroyOwner === me) { operation.destroy(); } return; } if (exception) { me.fireEvent('exception', me, response, operation); } else { meta = resultSet.getMetadata(); if (meta) { me.onMetaChange(meta); } } if (me.destroyed) { if (!operation.destroyed && destroyOp && operation.$destroyOwner === me) { operation.destroy(); } return; } me.afterRequest(request, success); me.fireEvent('endprocessresponse', me, response, operation); if (!operation.destroyed && destroyOp && operation.$destroyOwner === me) { operation.destroy(); } }, 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, needsEncoding, i, filter, encodedFilter; for (i = 0; i < length; i++) { filter = filters[i]; filter.getFilterFn(); if (filter.generatedFilterFn) { encodedFilter = filter.serialize(); needsEncoding |= !this.primitiveRe.test(typeof encodedFilter); out.push(encodedFilter); } } return needsEncoding ? this.applyEncoding(out) : 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(); if (groupDirectionParam === groupParam) { params[groupParam] += ' ' + grouper.getDirection(); } else { params[groupDirectionParam] = grouper.getDirection(); } } else { params[groupParam] = me.encodeSorters([ grouper ], true); } } if (sortParam && sorters && sorters.length > 0) { if (simpleSortMode) { for (index = (sorters.length > 1 && hasGroups) ? 1 : 0; index < sorters.length; index++) { if (directionParam === sortParam) { params[sortParam] = Ext.Array.push(params[sortParam] || [], sorters[index].getProperty() + ' ' + sorters[index].getDirection()); } else { params[sortParam] = Ext.Array.push(params[sortParam] || [], sorters[index].getProperty()); params[directionParam] = Ext.Array.push(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.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, callback, scope) { Ext.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() { var me = this; me.destroying = true; me.reader = me.writer = Ext.destroy(me.reader, me.writer); me.callParent(); me.destroying = false; me.destroyed = true; } }); Ext.define('Ext.data.proxy.Ajax', { extend: Ext.data.proxy.Server, alias: 'proxy.ajax', alternateClassName: [ 'Ext.data.HttpProxy', 'Ext.data.AjaxProxy' ], isAjaxProxy: true, 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 (me.responseType != null && Ext.supports.XHR2) { request.setResponseType(me.responseType); } 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) { return function(options, success, response) { var me = this; if (request === me.lastRequest) { me.lastRequest = null; } if (!me.destroying && !me.destroyed) { me.processResponse(success, operation, request, response); } }; }, destroy: function() { this.lastRequest = null; this.callParent(); } }); Ext.define('Ext.data.reader.Json', { extend: Ext.data.reader.Reader, alternateClassName: 'Ext.data.JsonReader', alias: 'reader.json', config: { record: null, metaProperty: 'metaData', useSimpleAccessors: false, preserveRawData: false }, responseType: 'json', updateRootProperty: function() { this.forceBuildExtractors(); }, updateMetaProperty: function() { this.forceBuildExtractors(); }, getResponseData: function(response) { var error; if (typeof response.responseJson === 'object') { return response.responseJson; } try { return Ext.decode(response.responseText); } catch (ex) { error = this.createReadError(ex.message); Ext.Logger.warn('Unable to parse the JSON returned by the server'); this.fireEvent('exception', this, response, error); return error; } }, buildExtractors: function(force) { var me = this, emptyFn = Ext.emptyFn, prop; if (me.callParent([ force ])) { me.getRoot = me.setupExtractor(me.getRootProperty(), Ext.identityFn); me.getGroupRoot = me.setupExtractor(me.getGroupRootProperty(), emptyFn); me.getSummaryRoot = me.setupExtractor(me.getSummaryRootProperty(), emptyFn); me.getMeta = me.setupExtractor(me.getMetaProperty(), emptyFn); } }, 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 simple = this.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 == null ? null : 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, self) { return field.mapping(raw, self); }; } else { return me.createAccessor(map); } } }, getAccessorKey: function(prop) { var simple = this.getUseSimpleAccessors() ? 'simple' : ''; return this.callParent([ simple + prop ]); }, privates: { copyFrom: function(reader) { this.callParent([ reader ]); this.getRoot = reader.getRoot; }, setupExtractor: function(prop, defaultFn) { return prop ? this.getAccessor(prop) : defaultFn; } } }); 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.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.SorterCollection', { extend: Ext.util.Collection, 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.raise('Invalid sort descriptor: ' + property); } sorters = [ property ]; mode = direction; direction = null; } if (mode && !me._sortModes[mode]) { Ext.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(); } }, clear: function() { this.beginUpdate(); this.callParent(); this.endUpdate(this.items); }, 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.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.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, 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); }, getFilterCount: function() { var filters = this.items, len = filters.length, i; for (i = len - 1; i >= 0; i--) { if (filters[i].getDisabled()) { len--; } } return len; }, 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.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.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, isGroupCollection: true, config: { grouper: null, groupConfig: null, itemRoot: null }, observerPriority: -100, emptyGroupRetainTime: 300000, constructor: function(config) { this.emptyGroups = {}; this.callParent([ config ]); this.on('remove', 'onGroupRemove', this); }, getItemGroup: function(item) { var key = this.getGrouper().getGroupString(item); return this.get(key); }, onCollectionAdd: function(source, details) { if (!this.isConfiguring) { this.addItemsToGroups(source, details.items, details.at); } }, onCollectionBeforeItemChange: function(source, details) { this.changeDetails = details; }, onCollectionBeginUpdate: function() { this.beginUpdate(); }, onCollectionEndUpdate: function() { this.endUpdate(); }, onCollectionItemChange: function(source, details) { if (!details.indexChanged) { this.syncItemGrouping(source, details); } this.changeDetails = null; }, onCollectionRefresh: function(source) { if (source.generation) { var me = this, itemGroupKeys = me.itemGroupKeys = {}, groupData = me.createEntries(source, source.items), entries = groupData.entries, groupKey, i, len, entry, j; for (i = 0 , len = entries.length; i < len; ++i) { entry = entries[i]; entry.group.splice(0, 1.0E99, entry.items); for (j = 0; j < entry.items.length; j++) { itemGroupKeys[source.getKey(entry.items[j])] = entry.group; } } entries = null; for (groupKey in me.map) { if (!(groupKey in groupData.groups)) { (entries || (entries = [])).push(me.map[groupKey]); } } if (entries) { me.remove(entries); } me.sortItems(); } }, onCollectionRemove: function(source, details) { var me = this, changeDetails = me.changeDetails, itemGroupKeys = me.itemGroupKeys || (me.itemGroupKeys = {}), entries, entry, group, i, n, j, removeGroups, item; if (source.getCount()) { if (changeDetails) { item = changeDetails.item || changeDetails.items[0]; entries = me.createEntries(source, [ item ]).entries; entries[0].group = itemGroupKeys['oldKey' in details ? details.oldKey : source.getKey(item)]; } else { entries = me.createEntries(source, details.items).entries; } for (i = 0 , n = entries.length; i < n; ++i) { group = (entry = entries[i]).group; if (group) { group.remove(entry.items); } for (j = 0; j < entry.items.length; j++) { delete itemGroupKeys[source.getKey(entry.items[j])]; } if (group && !group.length) { (removeGroups || (removeGroups = [])).push(group); } } } else { me.itemGroupKeys = {}; removeGroups = me.items; for (i = 0 , n = removeGroups.length; i < n; ++i) { removeGroups[i].clear(); } } 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) { if (!details.indexChanged) { details.oldIndex = source.indexOf(details.item); this.syncItemGrouping(source, details); } }, addItemsToGroups: function(source, items, at, oldIndex) { var me = this, itemGroupKeys = me.itemGroupKeys || (me.itemGroupKeys = {}), entries = me.createEntries(source, items).entries, index = -1, sourceStartIndex, entry, i, len, j, group, firstIndex, item; for (i = 0 , len = entries.length; i < len; ++i) { entry = entries[i]; group = entry.group; if (oldIndex || oldIndex === 0) { item = items[0]; if (group.getCount() > 0 && source.getSorters().getCount() === 0) { firstIndex = source.indexOf(group.items[0]); if (oldIndex < firstIndex) { index = 0; } else { index = oldIndex - firstIndex; } } if (index === -1) { group.add(item); } else { group.insert(index, item); } } else { if (me.length > 1 && at) { sourceStartIndex = source.indexOf(entries[0].group.getAt(0)); at = Math.max(at - sourceStartIndex, 0); } entry.group.insert(at != null ? at : group.items.length, entry.items); for (j = 0; j < entry.items.length; j++) { itemGroupKeys[source.getKey(entry.items[j])] = entry.group; } } } me.sortItems(); }, createEntries: function(source, items) { var me = this, groups = {}, entries = [], grouper = me.getGrouper(), entry, group, groupKey, i, item, len; for (i = 0 , len = items.length; i < len; ++i) { groupKey = grouper.getGroupString(item = items[i]); if (!(entry = groups[groupKey])) { group = me.getGroup(source, groupKey); entries.push(groups[groupKey] = entry = { group: group, items: [] }); } entry.items.push(item); } return { groups: groups, entries: entries }; }, syncItemGrouping: function(source, details) { var me = this, itemGroupKeys = me.itemGroupKeys || (me.itemGroupKeys = {}), item = details.item, oldKey, itemKey, oldGroup, group; itemKey = source.getKey(item); oldKey = 'oldKey' in details ? details.oldKey : itemKey; oldGroup = itemGroupKeys[oldKey]; group = me.getGroup(source, me.getGrouper().getGroupString(item)); details.group = group; details.oldGroup = oldGroup; if (!(details.groupChanged = group !== oldGroup)) { oldGroup.itemChanged(item, details.modified, details.oldKey, details); } else { if (oldGroup) { oldGroup.updateKey(item, oldKey, itemKey); oldGroup.remove(item); if (!oldGroup.length) { me.remove(oldGroup); } } me.addItemsToGroups(source, [ item ], null, details.oldIndex); } delete itemGroupKeys[oldKey]; itemGroupKeys[itemKey] = group; }, getGroup: function(source, key) { var me = this, group = me.get(key), autoSort = me.getAutoSort(); if (group) { group.setSorters(source.getSorters()); } else { group = me.emptyGroups[key] || Ext.create(Ext.apply({ xclass: 'Ext.util.Group', groupKey: key, rootProperty: me.getItemRoot(), sorters: source.getSorters() }, me.getGroupConfig())); group.ejectTime = null; me.setAutoSort(false); me.add(group); me.setAutoSort(autoSort); } 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() { var me = this; me.$groupable = null; me.destroyGroups(me.items); Ext.undefer(me.checkRemoveQueueTimer); me.callParent(); }, privates: { destroyGroups: function(groups) { var len = groups.length, i; for (i = 0; i < len; ++i) { groups[i].destroy(); } }, onGroupRemove: function(collection, info) { var me = this, groups = info.items, emptyGroups = me.emptyGroups, len, group, i; groups = Ext.Array.from(groups); for (i = 0 , len = groups.length; i < len; i++) { group = groups[i]; group.setSorters(null); emptyGroups[group.getGroupKey()] = group; group.ejectTime = Ext.now(); } me.checkRemoveQueue(); }, checkRemoveQueue: function() { var me = this, emptyGroups = me.emptyGroups, groupKey, group, reschedule; for (groupKey in emptyGroups) { group = emptyGroups[groupKey]; if (!group.getCount() && Ext.now() - group.ejectTime > me.emptyGroupRetainTime) { Ext.destroy(group); delete emptyGroups[groupKey]; } else { reschedule = true; } } if (reschedule) { Ext.undefer(me.checkRemoveQueueTimer); me.checkRemoveQueueTimer = Ext.defer(me.checkRemoveQueue, me.emptyGroupRetainTime, me); } } } }); Ext.define('Ext.data.Store', { extend: Ext.data.ProxyStore, alias: 'store.store', mixins: [ Ext.data.LocalStore ], config: { data: undefined, 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.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 ]); data = me.inlineData; if (data) { delete me.inlineData; me.loadInlineData(data); } }, 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(); if (proxy && proxy.isMemoryProxy) { proxy.setData(data); me.suspendEvents(); me.read(); me.resumeEvents(); } else { me.removeAll(true); me.suspendEvents(); me.loadData(data); me.resumeEvents(); } }, onCollectionAdd: function(collection, info) { this.loadCount = this.loadCount || 1; 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.removed, ignoreAdd = me.ignoreCollectionAdd, session = me.getSession(), replaced = info && info.replaced, i, sync, record, replacedItems; if (me.activeRanges) { me.syncActiveRanges(); } 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) { if (info.replaced) { if (lastChunk) { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); } } else { me.fireEvent('add', me, records, info.at); if (lastChunk) { me.fireEvent('datachanged', me); } } } if (replacedItems) { me.setMoving(replacedItems, false); } me.needsSync = me.needsSync || sync; }, onCollectionBeforeItemChange: function(collection, info) { var record = info.item, modifiedFieldNames = info.modified || null, type = info.meta; this.fireEvent('beforeupdate', this, record, type, modifiedFieldNames, info); }, 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); me.fireEvent('datachanged', me); } }, 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.getDataSource(), len, i, toRemove, record; if (records) { if (records.isModel) { if (data.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, replacement = info.replacement, isMove = me.removeIsMove || (replacement && Ext.Array.equals(records, replacement.items)), silent = me.removeIsSilent, lastChunk = !info.next, data = me.getDataSource(), i, record; if (me.ignoreCollectionRemove) { return; } if (replacement) { me.setMoving(replacement.items, true); } for (i = len - 1; i >= 0; 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) { if (!replacement || !replacement.items.length) { me.fireEvent('remove', me, records, index, isMove); if (lastChunk) { me.fireEvent('datachanged', me); } } } if (replacement) { me.setMoving(replacement.items, false); } }, onFilterEndUpdate: function() { var me = this; if (me.destroying || me.destroyed) { return; } if (me.activeRanges) { me.syncActiveRanges(); } me.callParent(arguments); me.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(), 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); }, onProxyLoad: function(operation) { var me = this, resultSet = operation.getResultSet(), records = operation.getRecords(), successful = operation.wasSuccessful(); if (me.destroyed) { return; } if (resultSet) { me.totalCount = resultSet.getTotal(); } if (successful) { records = me.processAssociation(records); me.loadRecords(records, operation.getAddRecords() ? { addRecords: true } : undefined); me.attachSummaryRecord(resultSet); } else { me.loading = false; } if (me.hasListeners.load) { me.fireEvent('load', me, records, successful, operation); } me.callObservers('AfterLoad', [ records, successful, operation ]); }, onProxyWrite: function(operation) { if (operation.wasSuccessful()) { this.attachSummaryRecord(operation.getResultSet()); } this.callParent([ operation ]); }, filterDataSource: function(fn) { var source = this.getDataSource(), items = source.items, len = items.length, ret = [], i; for (i = 0; i < len; i++) { if (fn.call(source, items[i])) { ret.push(items[i]); } } return ret; }, getNewRecords: function() { return this.filterDataSource(this.filterNew); }, getRejectRecords: function() { return this.filterDataSource(this.filterRejects); }, getUpdatedRecords: function() { return this.filterDataSource(this.filterUpdated); }, 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); } if (!me.isEmptyStore) { ++me.loadCount; me.complete = true; } if (me.hasListeners.datachanged) { me.fireEvent('datachanged', me); } if (me.hasListeners.refresh) { 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.getDataSource(), clearRemovedOnLoad = me.getClearRemovedOnLoad(), needsUnjoinCheck = removed && isLoad && !clearRemovedOnLoad, records, record, i, len; 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); me.fireEvent('commit', me); }, filterNewOnly: function(item) { return item.phantom === true; }, filterRejects: function(item) { return item.phantom || item.dirty; }, 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.getRawRemovedRecords(); 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); me.fireEvent('reject', me); }, doDestroy: function() { var me = this, task = me.loadTask, data = me.getData(), source = data.getSource(); me.clearData(); me.setSession(null); me.observers = null; if (task) { task.cancel(); me.loadTask = null; } if (source) { source.destroy(); } me.callParent(); }, privates: { commitOptions: { commit: true }, attachSummaryRecord: function(resultSet) { if (!resultSet) { return; } var me = this, summary = resultSet.getSummaryData(), grouper = me.getGrouper(), current = me.summaryRecord, commitOptions = me.commitOptions, groups, len, i, rec, group; if (summary) { if (current) { current.set(summary.data, commitOptions); } else { me.summaryRecord = summary; summary.isRemote = true; } } if (grouper) { summary = resultSet.getGroupData(); if (summary) { groups = me.getGroups(); for (i = 0 , len = summary.length; i < len; ++i) { rec = summary[i]; group = groups.getItemGroup(rec); if (group) { current = group.summaryRecord; if (current) { current.set(rec.data, commitOptions); } else { group.summaryRecord = rec; rec.isRemote = true; } } } } } }, fetch: function(options) { options = Ext.apply({}, options); this.setLoadOptions(options); var operation = this.createOperation('read', options); operation.execute(); }, fireChangeEvent: function(record) { return this.getDataSource().contains(record); }, 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; }, setLoadOptions: function(options) { var me = this, pageSize = me.getPageSize(), session, grouper; if (me.getRemoteSort() && !options.grouper) { grouper = me.getGrouper(); if (grouper) { options.grouper = grouper; } } 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; } } me.callParent([ options ]); }, 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' ], 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, 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, defaultType) { if (Ext.isArray(store)) { var first = store[0], data = store, arrays, fields, i, len; if (Ext.isObject(first)) { store = { data: data }; } else { arrays = Ext.isArray(first); fields = [ 'field1' ]; if (arrays) { for (i = 2 , len = first.length; i <= len; ++i) { fields.push('field' + i); } } else { data = []; for (i = 0 , len = store.length; i < len; ++i) { data.push([ store[i] ]); } } return new Ext.data.ArrayStore({ data: data, fields: fields, autoDestroy: true, autoCreated: true, expanded: !arrays }); } } if (Ext.isString(store)) { return this.get(store); } else { return Ext.Factory.store(store, defaultType); } }, getKey: function(o) { return o.storeId; }, addEmptyStore: function() { var emptyStore = this.$emptyStore, destoryable = { destroy: Ext.emptyFn }; if (!emptyStore) { emptyStore = this.$emptyStore = Ext.regStore('ext-empty-store', { proxy: 'memory', useModelWarning: false }); emptyStore.isEmptyStore = true; emptyStore.on = emptyStore.addListener = function() { return destoryable; }; emptyStore.un = emptyStore.removeListener = Ext.emptyFn; emptyStore.add = emptyStore.remove = emptyStore.insert = emptyStore.destroy = emptyStore.loadData = function() { Ext.raise('Cannot modify ext-empty-store'); }; } this.add(emptyStore); }, clear: function() { this.callParent(); this.addEmptyStore(); } }, function() { Ext.regStore = function(id, config) { var store; if (Ext.isObject(id)) { config = id; } else { if (Ext.data.StoreManager.containsKey(id)) { return Ext.data.StoreManager.lookup(id); } config.storeId = id; } 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); }; Ext.data.StoreManager.addEmptyStore(); }); Ext.define('Ext.app.domain.Store', { extend: Ext.app.EventDomain, singleton: true, 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.Controller', { extend: Ext.app.BaseController, 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\./, profileRegex: /^(.*)\.profile\./, 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, namespaceRe = cls.prototype.isProfile ? Controller.profileRegex : Controller.controllerRegex, className, namespace, match; className = Ext.getClassName(cls); namespace = data.$namespace || data.namespace || Ext.app.getNamespace(className) || ((match = namespaceRe.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, profileName) { 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, profileName); names[j] = absoluteName = o.absoluteName; shortName = o.shortName; requires.push(absoluteName); getterName = me.getGetterName(shortName, strings.upper); if (!cls[getterName]) { cls[getterName] = getter = me.createGetter(strings.getter, name); } else if (getterName === 'getMainView') { Ext.log.warn('Cannot have a view named \'Main\' - getter conflicts with mainView config.'); } if (getter && kind !== 'controller') { getter['Ext.app.getter'] = true; } } }, getFullName: function(name, kind, namespace, profileName) { 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; shortName = name.replace(namespace + '.' + kind + '.', ''); } else { if (!namespace) { Ext.log.warn("Cannot find namespace for " + kind + " " + name + ", " + "assuming it is fully qualified class name"); } if (namespace) { absoluteName = namespace + '.' + kind + '.' + (profileName ? profileName + '.' + name : 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([ config ]); }, 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; }, applyId: function(id) { return id || Ext.app.Controller.getFullName(this.$className, 'controller', this.$namespace).shortName; }, 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('destroy', 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, { id: storeId }); } } return store; }, getModel: function(modelName) { var name = Ext.app.Controller.getFullName(modelName, 'model', this.$namespace), ret = Ext.ClassManager.get(name.absoluteName); if (!ret) { ret = Ext.data.schema.Schema.lookupEntity(modelName); } 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); }, 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, isApplication: true, scope: undefined, namespaces: [], paths: null, config: { name: '', appProperty: 'app', profiles: [], currentProfile: null, mainView: { $value: null, lazy: true }, defaultToken: null, glyphFontFamily: null, quickTips: true, router: null }, onClassExtended: function(cls, data, hooks) { var Controller = Ext.app.Controller, proto = cls.prototype, requires = [], onBeforeClassCreated, paths, namespace, ns; namespace = data.name || cls.superclass.name; if (namespace) { data.$namespace = namespace; Ext.app.addNamespaces(namespace); } if (data.namespaces) { Ext.app.addNamespaces(data.namespaces); } if (data['paths processed']) { delete data['paths processed']; } else { Ext.app.setupPaths(namespace, ('appFolder' in data) ? data.appFolder : cls.superclass.appFolder, data.paths); } 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); if (data.__handleRequires) { data.__handleRequires.call(this, requires, Ext.bind(function() { return onBeforeClassCreated.apply(this, args); }, this)); return; } Ext.require(requires, function() { return onBeforeClassCreated.apply(this, args); }); }; } }, getDependencies: Ext.emptyFn, constructor: function(config) { var me = this; Ext.route.Router.application = me; me.callParent([ config ]); if (Ext.isEmpty(me.getName())) { Ext.raise("[Ext.app.Application] Name property is required"); } me.doInit(me); Ext.on('appupdate', me.onAppUpdate, me, { single: true }); Ext.Loader.setConfig({ enabled: true }); this.onProfilesReady(); }, applyId: function(id) { return id || this.$className; }, updateRouter: function(cfg) { if (cfg) { Ext.route.Router.setConfig(cfg); } }, onAppUpdate: Ext.emptyFn, onProfilesReady: function() { var me = this, profiles = me.getProfiles(), length = profiles.length, current, i, instance; for (i = 0; i < length; i++) { instance = Ext.create(profiles[i], { application: me }); if (instance.isActive() && !current) { current = instance; me.setCurrentProfile(current); } } if (current) { current.init(); } me.initControllers(); me.onBeforeLaunch(); me.finishInitControllers(); }, doInit: function(app) { this.initNamespace(app); this.callParent([ app ]); }, initNamespace: function(me) { var appProperty = me.getAppProperty(), 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), profile = me.getCurrentProfile(), i, ln; me.controllers = new Ext.util.MixedCollection(); for (i = 0 , ln = controllers.length; i < ln; i++) { me.getController(controllers[i]); } if (profile) { controllers = profile.getControllers(); for (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 || token === defaultToken) { Ext.route.Router.onStateChange(token); } else if (defaultToken) { History.replace(defaultToken); } if (Ext.Microloader && Ext.Microloader.appUpdate && Ext.Microloader.appUpdate.updated) { Ext.Microloader.fireAppUpdate(); } if (!me.cnsTimer) { me.cnsTimer = Ext.defer(Ext.ClassManager.clearNamespaceCache, 2000, Ext.ClassManager); } }, 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 = this.getView(value); return view.create({ $initParent: this.viewport }); }, 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: className }); 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.undefer(me.cnsTimer); Ext.un('appupdate', me.onAppUpdate, me); 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]; } if (Ext.route.Router.application === me) { Ext.route.Router.application = null; } if (Ext.app.Application.instance === me) { Ext.app.Application.instance = null; } }, updateGlyphFontFamily: function(fontFamily) { Ext.setGlyphFontFamily(fontFamily); }, applyProfiles: function(profiles) { var me = this; return Ext.Array.map(profiles, function(profile) { return me.getModuleClassName(profile, "profile"); }); } }, function() { Ext.getApplication = function() { return Ext.app.Application.instance; }; }); Ext.application = function(config) { var createApp = function(App) { Ext.onReady(function() { var Viewport = Ext.viewport; Viewport = Viewport && Viewport['Viewport']; if (Viewport && Viewport.setup) { Viewport.setup(App.prototype.config.viewport); } Ext.app.Application.instance = new App(); }); }; if (typeof config === "string") { Ext.require(config, function() { createApp(Ext.ClassManager.get(config)); }); } else { config = Ext.apply({ extend: 'Ext.app.Application' }, config); Ext.app.setupPaths(config.name, config.appFolder, config.paths); config['paths processed'] = true; Ext.define(config.name + ".$application", config, function() { createApp(this); }); } }; Ext.define('Ext.util.ItemCollection', { extend: Ext.util.MixedCollection, alternateClassName: 'Ext.ItemCollection', getKey: function(item) { return item.getItemId && item.getItemId(); }, has: function(item) { return this.map.hasOwnProperty(item.getId()); } }); 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.mixin.Container', { extend: Ext.Mixin, mixinConfig: { id: 'container' }, isContainer: true, nameHolder: false, referenceHolder: false, getNamedItems: function() { var CM = Ext.ComponentManager; if (CM.referencesDirty) { CM.fixReferences(); } return this.nameRefs || null; }, getReferences: function() { var CM = Ext.ComponentManager; if (CM.referencesDirty) { CM.fixReferences(); } return this.refs || null; }, lookup: function(ref) { var refs = this.getReferences(); return (refs && refs[ref]) || null; }, lookupName: function(name) { var items = this.getNamedItems(); return (items && items[name]) || null; }, lookupReference: function(ref) { return this.lookup(ref); }, privates: { attachNameRef: function(component) { var me = this, key = component.name || component._name, entry, nameRefs; if (key && !me.destroying && !me.destroyed) { nameRefs = me.nameRefs || (me.nameRefs = {}); entry = nameRefs[key]; if (!entry) { entry = component.shareableName ? [ component ] : component; } else if (!entry.isInstance) { entry.push(component); } else { Ext.raise('Duplicate name: "' + key + '" on ' + me.id + ' between ' + entry.id + ' and ' + component.id); } nameRefs[key] = entry; } }, attachReference: function(component) { var me = this, key, refs; if (!me.destroying && !me.destroyed) { 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; } }, containerOnAdded: function(component, instanced) { if (instanced) { Ext.ComponentManager.markReferencesDirty(); } }, containerOnRemoved: function(destroying) { if (!destroying) { Ext.ComponentManager.markReferencesDirty(); } }, initContainerInheritedState: function(inheritedState, inheritedStateInner) { var me = this, controller = me.getController(), session = me.getSession(), viewModel = me.getConfig('viewModel', true), reference = me.reference, referenceHolder = me.referenceHolder; if (me.nameHolder) { inheritedState.nameHolder = me; } 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 + '.'; } }, setupReference: function(reference) { var len; if (reference && reference.charAt(len = reference.length - 1) === '>') { this.isParentReference = true; reference = reference.substring(0, len); } if (reference && !Ext.validIdRe.test(reference)) { Ext.Error.raise('Invalid reference "' + reference + '" for ' + this.getId() + ' - not a valid identifier'); } return reference; } } }); 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) { Ext.raise("Legacy multi-argument KeyMap constructor is removed. Use a config object instead."); } 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(); }, 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.ctrl === item.ctrl && 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, result; if (me.enabled) { bindings = me.bindings; 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 = 0 , len = bindings.length; i < len; i++) { result = me.processBinding(bindings[i], event); if (result === false) { me.processing = false; return result; } } 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, result; if (keyCode.test) { if (keyCode.test(String.fromCharCode(event.getCharCode()))) { result = handler.call(scope, key, event); if (result !== true && defaultEventAction) { event[defaultEventAction](); } if (result === false) { return result; } } } else if (keyCode.length) { for (i = 0 , len = keyCode.length; i < len; i++) { if (key === keyCode[i]) { result = handler.call(scope, key, event); if (result !== true && defaultEventAction) { event[defaultEventAction](); } if (result === false) { return result; } break; } } } } }, checkModifiers: function(binding, event) { var keys = [ 'shift', 'ctrl', 'alt' ], i, len, val, key; for (i = 0 , len = keys.length; 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, priority: me.priority }); me.enabled = true; } }, disable: function() { var me = this; if (me.enabled) { if (!me.target.destroyed) { 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(); me.target = null; if (removeTarget) { target.destroy(); Ext.raise("Using removeTarget argument in KeyMap destructor is not supported."); } me.callParent(); } }); Ext.define('Ext.util.KeyNav', { alternateClassName: 'Ext.KeyNav', 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, keymapCfg, map; if (arguments.length === 2) { Ext.raise("2-argument KeyNav constructor is removed. Use a config object instead."); } config = config || {}; keymapCfg = { target: config.target, ignoreInputFields: config.ignoreInputFields, eventName: me.getKeyEvent('forceKeyDown' in config ? config.forceKeyDown : me.forceKeyDown, config.eventName), capture: config.capture }; if (me.map) { me.map.destroy(); } me.initConfig(config); if (config.processEvent) { keymapCfg.processEvent = config.processEvent; keymapCfg.processEventScope = config.processEventScope || me; } if (config.priority) { keymapCfg.priority = config.priority; } if (config.keyMap) { map = me.map = config.keyMap; } else { map = me.map = new Ext.util.KeyMap(keymapCfg); me.destroyKeyMap = true; } me.addBindings(config); map.disable(); if (!config.disabled) { map.enable(); } }, addBindings: function(bindings) { var me = this, map = me.map, keyCodes = Ext.util.KeyNav.keyOptions, Event = Ext.event.Event, defaultScope = bindings.scope || me, binding, keyName, keyCode; for (keyName in bindings) { binding = bindings[keyName]; keyCode = keyName.length === 1 ? keyName.charCodeAt(0) : (keyCodes[keyName] || Event[keyName.toUpperCase()]); if (keyCode != null) { keyName = keyCode; } if (binding && (keyName.length === 1 || !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) { var me = this; if (removeEl) { Ext.raise("removeEl argument in KeyNav destructor is not supported anymore."); } if (me.destroyKeyMap) { me.map.destroy(removeEl); } me.map = null; me.callParent(); }, 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; }, isEnabled: function() { return !this.disabled; }, getKeyEvent: function(forceKeyDown, configuredEventName) { if (forceKeyDown || (Ext.supports.SpecialKeyDownRepeat && !configuredEventName)) { return 'keydown'; } else { return configuredEventName || this.eventName; } } }); Ext.define('Ext.mixin.FocusableContainer', { extend: Ext.Mixin, mixinConfig: { id: 'focusablecontainer' }, isFocusableContainer: true, focusableContainer: false, resetFocusPosition: false, activeChildTabIndex: 0, inactiveChildTabIndex: -1, allowFocusingDisabledChildren: false, focusableContainerEl: 'el', privates: { initFocusableContainer: function(clearChildren) { var items, i, len; if (this.focusableContainer) { clearChildren = clearChildren != null ? clearChildren : true; this.doInitFocusableContainer(clearChildren); } else { items = this.getFocusables(); for (i = 0 , len = items.length; i < len; i++) { items[i].ownerFocusableContainer = null; } } }, doInitFocusableContainer: function(clearChildren) { var me = this, el = me.focusableContainerEl, child; if (!el.isElement) { el = me.focusableContainerEl = me[el]; } if (me.initFocusableContainerKeyNav) { me.initFocusableContainerKeyNav(el); } if (clearChildren) { me.clearFocusables(); if (!me.isDisabled()) { child = me.findNextFocusableChild({ step: 1 }) || me.findNextFocusableChild({ beforeRender: true }); if (child) { me.activateFocusable(child); } } } child = me.findNextFocusableChild({ firstTabbable: true }); me.activateFocusableContainer(!!child && !me.isDisabled()); }, initFocusableContainerKeyNav: function(el) { var me = this; if (!me.focusableKeyNav) { el = el || me.focusableContainerEl; me.focusableKeyNav = new Ext.util.KeyNav({ target: el, disabled: true, eventName: 'keydown', processEvent: me.processFocusableContainerKeyEvent, processEventScope: me, scope: me, tab: me.onFocusableContainerTabKey, enter: { handler: me.onFocusableContainerEnterKey, ctrl: false, shift: false, alt: false }, space: { handler: me.onFocusableContainerSpaceKey, ctrl: false, shift: false, alt: false }, up: { handler: me.onFocusableContainerUpKey, ctrl: false, shift: false, alt: false }, down: { handler: me.onFocusableContainerDownKey, ctrl: false, shift: false, alt: false }, left: { handler: me.onFocusableContainerLeftKey, ctrl: false, shift: false, alt: false }, right: { handler: me.onFocusableContainerRightKey, ctrl: false, shift: false, alt: false } }); } }, destroyFocusableContainer: function() { this.focusableKeyNav = Ext.destroy(this.focusableKeyNav); }, activateFocusableContainer: function(enable) { var keyNav = this.focusableKeyNav; if (keyNav) { keyNav.setDisabled(!enable); } }, isFocusableContainerActive: function() { var keyNav = this.focusableKeyNav; return keyNav ? !keyNav.disabled : false; }, getFocusables: function() { return this.items.items; }, initDefaultFocusable: function() { var me = this, haveFocusable = false, items, item, i, len; items = me.getFocusables(); len = items.length; if (!len) { return; } for (i = 0; i < len; i++) { item = items[i]; if (!item.isDisabled() && item.isFocusable()) { haveFocusable = true; break; } } if (!haveFocusable) { return; } item = me.findNextFocusableChild({ items: items, step: true }); if (item) { me.activateFocusable(item); } return item; }, clearFocusables: function(skipFocused) { var me = this, items = me.getFocusables(), len = items.length, item, i; for (i = 0; i < len; i++) { item = items[i]; if (!item.destroyed && item.focusable && item.isTabbable()) { me.deactivateFocusable(item); } } }, processFocusableContainerKeyEvent: function(e) { if (!Ext.fly(e.target).isInputField()) { return e; } }, activateFocusable: function(child) { child.setTabIndex(this.activeChildTabIndex); }, deactivateFocusable: function(child) { child.setTabIndex(this.inactiveChildTabIndex); }, onFocusableContainerTabKey: function() { return true; }, onFocusableContainerEnterKey: function() { return true; }, onFocusableContainerSpaceKey: function() { return true; }, onFocusableContainerUpKey: function(e) { e.preventDefault(); return this.moveChildFocus(e, false); }, onFocusableContainerDownKey: function(e) { e.preventDefault(); return this.moveChildFocus(e, true); }, onFocusableContainerLeftKey: function(e) { e.preventDefault(); return this.moveChildFocus(e, false); }, onFocusableContainerRightKey: function(e) { e.preventDefault(); return this.moveChildFocus(e, true); }, getFocusableFromEvent: function(e) { var child = Ext.Component.from(e); if (!child) { Ext.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: child, step: forward }); if (nextChild) { nextChild.focus(); } return nextChild; }, findNextFocusableChild: function(options) { var beforeRender = options.beforeRender, firstTabbable = options.firstTabbable, items, item, child, step, idx, i, len, allowDisabled; items = options.items || this.getFocusables(); step = options.step != null ? options.step : 1; child = options.child; allowDisabled = !!this.allowFocusingDisabledChildren; 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 || (item.isDisabled() && !allowDisabled)) { continue; } if (firstTabbable) { if (item.isTabbable && item.isTabbable()) { return item; } } else if (beforeRender || (item.isFocusable && item.isFocusable())) { return item; } } return null; }, onFocusEnter: function(e) { var me = this, target = e.toComponent, child; if (target === me) { child = me.initDefaultFocusable(); if (child) { child.focus(); } } me.activateFocusableContainer(true); }, onFocusLeave: function(e) { var me = this; if (me.resetFocusPosition) { me.clearFocusables(); me.initDefaultFocusable(); } }, beforeFocusableChildBlur: Ext.privateFn, afterFocusableChildBlur: Ext.privateFn, beforeFocusableChildFocus: function(child) { var me = this; if (!me.focusableContainer || me.destroying || me.destroyed) { return; } me.clearFocusables(); me.activateFocusable(child); }, afterFocusableChildFocus: function(child) { var me = this; if (!me.focusableContainer || me.destroying || me.destroyed) { return; } me.lastFocusedChild = child; }, onFocusableChildAdd: function(child) { var me = this; if (child.focusable) { child.ownerFocusableContainer = me; } }, onFocusableChildRemove: function(child) { var me = this, next; child.ownerFocusableContainer = null; if (child === me.lastFocusedChild) { me.lastFocusedChild = null; next = me.initDefaultFocusable(); if (child.hasFocus) { next = next || child.findFocusTarget(); if (next) { next.focus(); } } } child = next || me.findNextFocusableChild({ step: 1, beforeRender: true }); if (!child) { me.activateFocusableContainer(false); } }, beforeFocusableChildEnable: Ext.privateFn, onFocusableChildEnable: function(child) { var me = this, active; if (!me.focusableContainer || me.destroying || me.destroyed) { return; } if (me.containsFocus) { active = Ext.ComponentManager.getActiveComponent(); me.clearFocusables(); me.activateFocusable(active); } else if (me.resetFocusPosition || me.lastFocusedChild == null) { me.clearFocusables(); if (child.hasFocus) { me.activateFocusable(child); active = child; } } else { me.deactivateFocusable(child); if (child === me.lastFocusedChild) { me.clearFocusables(); me.activateFocusable(child); } active = me.findNextFocusableChild({ firstTabbable: true }); } if (!active) { me.initDefaultFocusable(); } me.activateFocusableContainer(true); }, beforeFocusableChildDisable: function(child) { var me = this, next; if (!me.focusableContainer || me.destroying || me.destroyed) { return; } if (child.hasFocus) { next = me.findNextFocusableChild({ child: child }) || child.findFocusTarget(); if (next) { next.focus(); } } }, onFocusableChildDisable: function(child) { var me = this, next; if (!me.focusableContainer || me.destroying || me.destroyed) { return; } next = me.findNextFocusableChild({ firstTabbable: true }); if (!next) { next = me.initDefaultFocusable(); } if (!next) { me.activateFocusableContainer(false); } }, beforeFocusableChildHide: function(child) { return this.beforeFocusableChildDisable(child); }, onFocusableChildHide: function(child) { return this.onFocusableChildDisable(child); }, beforeFocusableChildShow: function(child) { return this.beforeFocusableChildEnable(child); }, onFocusableChildShow: function(child) { return this.onFocusableChildEnable(child); }, onFocusableChildMasked: Ext.privateFn, onFocusableChildDestroy: Ext.privateFn, onFocusableChildUpdate: Ext.privateFn }, deprecated: { 7: { configs: { enableFocusableContainer: 'focusableContainer' } } } }); Ext.define('Ext.mixin.Hookable', { extend: Ext.Mixin, mixinConfig: { id: 'hookable' }, bindHook: function(instance, boundMethod, bindingMethod, preventDefault, extraArgs) { instance.afterMethod(boundMethod, bindingMethod || boundMethod, this, preventDefault, extraArgs); return this; }, unbindHook: function(instance, boundMethod, bindingMethod) { instance.removeMethodListener(boundMethod, bindingMethod || boundMethod, this); return this; } }); Ext.define('Ext.app.Profile', { mixins: [ Ext.mixin.Observable ], isProfile: true, config: { 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; }, init: function() { var views = this.getViews(), xtype; if (views && !(views instanceof Array)) { for (xtype in views) { Ext.ClassManager.setXType(views[xtype], xtype); } } }, launch: Ext.emptyFn, onClassExtended: function(cls, data, hooks) { var onBeforeClassCreated = hooks.onBeforeCreated; hooks.onBeforeCreated = function(cls, data) { var Controller = Ext.app.Controller, className = cls.$className, requires = [], proto = cls.prototype, views = data.views, name, namespace; name = data.name; if (name) { delete data.name; } else { name = className.split('.'); name = name[name.length - 1]; } cls._name = name; cls._namespace = name = (data.namespace || name).toLowerCase(); delete data.namespace; namespace = Controller.resolveNamespace(cls, data); Controller.processDependencies(proto, requires, namespace, 'model', data.models, name); Controller.processDependencies(proto, requires, namespace, 'store', data.stores, name); Controller.processDependencies(proto, requires, namespace, 'controller', data.controllers, name); if (views) { if (views instanceof Array) { Controller.processDependencies(proto, requires, namespace, 'view', views, name); } else { Ext.app.Profile.processViews(className, views, requires); } } Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this)); }; }, getName: function() { return this.self._name; }, getNamespace: function() { return this.self._namespace; }, privates: { statics: { processViews: function(className, views, requires) { var body, cls, s, xtype; for (xtype in views) { cls = views[xtype]; if (typeof cls !== 'string') { s = cls.xclass; if (!s) { Ext.raise('Views must specify an xclass'); } body = Ext.apply({ extend: s }, cls); delete body.xclass; Ext.define(views[xtype] = className + '$' + xtype, body); cls = s; } requires.push(cls); } } } } }); Ext.define('Ext.app.domain.View', { extend: Ext.app.EventDomain, isInstance: true, constructor: function(controller) { this.callParent([ controller ]); this.controller = controller; this.monitoredClasses = [ Ext.Widget ]; }, 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, alias: 'controller.controller', mixins: [ Ext.mixin.Factoryable ], isViewController: true, factoryConfig: { type: 'controller' }, config: { bindings: { $value: null, lazy: true }, closeViewAction: 'destroy' }, view: null, constructor: function(config) { this.compDomain = new Ext.app.domain.View(this); this.callParent([ config ]); }, beforeInit: Ext.emptyFn, init: Ext.emptyFn, initViewModel: Ext.emptyFn, destroy: function() { var me = this, domain = me.compDomain, bind, b, key; if (me.$hasBinds) { bind = me.getBindings(); for (key in bind) { b = bind[key]; if (b) { b.destroy(); } } } 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 ]); }, applyId: function(id) { if (!id) { id = Ext.id(null, 'controller-'); } return id; }, getReferences: function() { var view = this.view; return view && view.getReferences(); }, getView: function() { return this.view; }, lookup: function(key) { var view = this.view; return view && view.lookup(key); }, lookupReference: function(key) { return this.lookup(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, args) { var view = this.view, result = false, a = arguments; if (view) { if (view !== args) { a = Ext.Array.slice(a); a.splice(1, 0, view); } result = view.fireEvent.apply(view, a); } return result; }, applyBindings: function(bindings) { if (!bindings) { return null; } var me = this, viewModel = me.getViewModel(), getBindTemplateScope = me.getBindTemplateScope(), b, fn, descriptor; me.$hasBinds = true; if (!viewModel) { Ext.raise('Cannot use bind config without a viewModel'); } for (fn in bindings) { descriptor = bindings[fn]; b = null; if (descriptor) { b = viewModel.bind(descriptor, fn, me); b.getTemplateScope = getBindTemplateScope; } bindings[fn] = b; } return bindings; }, privates: { view: null, attachReference: function(component) { var view = this.view; if (view) { view.attachReference(component); } }, getBindTemplateScope: function() { return this.scope; }, initBindings: function() { this.getBindings(); }, 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, beginUpdate: Ext.emptyFn, endUpdate: Ext.emptyFn, add: function(item) { var me = this, items = me.items, map = me.map, n = 1, old, i, idx, id, it, ret, was; if (Ext.isArray(item)) { old = ret = []; n = item.length; } for (i = 0; i < n; i++) { id = me.getKey(it = old ? item[i] : item); idx = map[id]; if (idx === undefined) { items.push(it); map[id] = me.length++; if (old) { old.push(it); } else { ret = it; } } else { was = items[idx]; if (old) { old.push(was); } else { ret = was; } items[idx] = it; } } ++me.generation; return ret; }, 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(); }, 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; }, getAt: function(index) { var out = null; if (index < this.length) { out = this.items[index]; } return out; }, get: function(key) { return this.getByKey(key); }, getByKey: function(key) { var map = this.map, ret = (key in map) ? this.items[map[key]] : null; return ret; }, indexOfKey: function(key) { var map = this.map, ret = (key in map) ? map[key] : -1; return ret; }, last: function() { return this.items[this.length - 1]; }, updateKey: function(item, oldKey) { var me = this, map = me.map, newKey; if (!item || !oldKey) { return; } if ((newKey = me.getKey(item)) !== oldKey) { if (me.getAt(map[oldKey]) === item && !(newKey in map)) { me.generation++; map[newKey] = map[oldKey]; delete map[oldKey]; } } else { if (newKey in map && me.getAt(map[newKey]) !== item) { Ext.raise('Duplicate newKey "' + newKey + '" for item with oldKey "' + oldKey + '"'); } if (oldKey in map && me.getAt(map[oldKey]) !== item) { Ext.raise('Incorrect oldKey "' + oldKey + '" for item with newKey "' + newKey + '"'); } } }, getCount: function() { return this.length; }, getKey: function(item) { return item.id || item.getId(); }, getRange: function(begin, end) { var items = this.items, length = items.length, range; if (!length) { range = []; } else { range = Ext.Number.clipIndices(length, [ begin, end ]); range = items.slice(range[0], range[1]); } return range; }, remove: function(item) { var me = this, map = me.map, items = me.items, ret = null, n = 1, changed, old, i, idx, id, last, was; if (Ext.isArray(item)) { n = item.length; old = ret = []; } if (me.length) { for (i = 0; i < n; i++) { idx = map[id = me.getKey(old ? item[i] : item)]; if (idx !== undefined) { delete map[id]; was = items[idx]; if (old) { old.push(was); } else { ret = was; } last = items.pop(); if (idx < --me.length) { items[idx] = last; map[me.getKey(last)] = idx; } changed = true; } } if (changed) { ++me.generation; } } return ret; }, removeByKey: function(key) { var item = this.getByKey(key); if (item) { this.remove(item); } return item || null; }, replace: function(item) { this.add(item); return item; }, 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 ], 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 }, suspendOnNotify: true, 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.items.destroy(); me.items = me.orderedItems = null; me.callParent(); 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.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.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.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, suspend = me.suspendOnNotify, busyCounter, i, item, len, queue, firedEvent; if (timer) { window.clearTimeout(timer); me.timer = null; } if (!me.firing && me.scheduledCount) { if (suspend) { Ext.suspendLayouts(); } 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 (suspend) { Ext.resumeLayouts(true); } } 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.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.raise('Exceeded cycleLimit ' + this.getCycleLimit()); }, scheduleItem: function(item) { if (!item) { Ext.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.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.destroyed || !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); }, abort: function() { var me = this, op; if (me.running) { op = me.getCurrent(); if (!op.destroyed) { op.abort(); } } me.running = false; me.aborted = true; me.current = undefined; }, 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(); } }, destroy: function() { var me = this, operations = me.operations, op, i, len; if (me.running) { me.abort(); } for (i = 0 , len = me.operations.length; i < len; i++) { op = operations[i]; if (op) { if (!op.destroyed && !op.$destroyOwner) { op.destroy(); } op[i] = null; } } me.operations = me.exceptions = null; me.callParent(); } }); Ext.define('Ext.data.matrix.Slice', { 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 }); }, commit: function() { var members = this.members, id; for (id in members) { members[id][2] = 0; } }, onStoreLoad: function(store) { this.update(store.getData().items, 0); }, update: function(recordsOrIds, state) { if (!(recordsOrIds instanceof Array)) { Ext.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 && !(state === 1 && assoc[2] === 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); } } } }, updateId: 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]; } }, 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', { constructor: function(matrix, index, role) { var me = this; me.matrix = matrix; me.index = index; me.role = role; me.slices = {}; }, commit: function() { var slices = this.slices, id; for (id in slices) { slices[id].commit(); } }, 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); }, updateId: function(oldId, newId) { var slice = this.get(oldId); if (slice) { slice.updateId(newId); } }, 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', { 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; }, commit: function() { this.left.commit(); this.right.commit(); }, update: function(id1, id2, state) { return this.left.update(id1, id2, state); }, updateId: function(record, oldId, newId) { var Type = record.self, left = this.left, right = this.right, matchSide; if (Type === left.role.cls) { matchSide = left; } if (Type === right.role.cls) { matchSide = right; } if (matchSide) { matchSide.updateId(oldId, newId); } }, 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, operationType, proxy, batchActions, records, len, i; if (map) { if (!batch) { batch = new Ext.data.Batch(); } for (name in map) { bucket = map[name]; entity = bucket.entity; proxy = entity.getProxy(); batchActions = proxy.getBatchActions(); delete bucket.entity; for (operationType in bucket) { if (batchActions) { operation = proxy.createOperation(operationType, { records: bucket[operationType] }); operation.entityType = entity; batch.add(operation); } else { records = bucket[operationType]; for (i = 0 , len = records.length; i < len; ++i) { operation = proxy.createOperation(operationType, { records: [ records[i] ] }); 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.mixin.Dirty', { mixinId: 'dirty', config: { dirty: { $value: false, lazy: true } }, dirty: false, _dirtyRecordCount: 0, ignoreDirty: false, recordStateIsDirtyState: true, isDirty: function() { return this.getDirty(); }, applyDirty: function(dirty) { return this.ignoreDirty ? false : dirty; }, updateDirty: function(dirty) { var me = this; me.dirty = dirty; if (me.fireEvent && !me.isDirtyInitializing) { me.fireDirtyChange(); } }, clearRecordStates: function() { var me = this, counters = me._crudCounters; if (counters) { counters.C = counters.U = counters.D = 0; } me._dirtyRecordCount = 0; if (me.recordStateIsDirtyState) { me.setDirty(false); } }, fireDirtyChange: function() { var me = this; if (!me.ignoreDirty && me.hasListeners.dirtychange) { me.fireEvent('dirtychange', me, me.dirty); } }, trackRecordState: function(record, initial) { var me = this, counters = me._crudCounters || (me._crudCounters = { C: 0, R: 0, U: 0, D: 0 }), dirtyRecordCountWas = me._dirtyRecordCount, state = record.crudState, stateWas = record.crudStateWas, changed, dirtyRecordCount; if (initial || state !== stateWas) { if (!initial && stateWas) { --counters[stateWas]; } if (!(record.phantom && state === 'D')) { ++counters[state]; } me.checkCounters(); me._dirtyRecordCount = dirtyRecordCount = counters.C + counters.U + counters.D; changed = !dirtyRecordCount !== !dirtyRecordCountWas; if (changed && me.recordStateIsDirtyState) { me.setDirty(dirtyRecordCount > 0); } } return changed; }, untrackRecordState: function(record) { var me = this, counters = me._crudCounters, dirtyRecordCountWas = me._dirtyRecordCount, state = record.crudState, changed, dirtyRecordCount; if (counters && state !== 'D' && !record.erased) { --counters[state]; me.checkCounters(); me._dirtyRecordCount = dirtyRecordCount = counters.C + counters.U + counters.D; changed = !dirtyRecordCount !== !dirtyRecordCountWas; if (changed && me.recordStateIsDirtyState) { me.setDirty(dirtyRecordCount > 0); } } return changed; }, checkCounters: function() { var counters = this._crudCounters, key; for (key in counters) { if (counters[key] < 0) { Ext.raise('Invalid state for ' + key); } } } }); Ext.define('Ext.data.Session', { mixins: [ Ext.mixin.Dirty, Ext.mixin.Observable ], isSession: true, config: { schema: 'default', parent: null, autoDestroy: true, crudProperties: { create: 'C', read: 'R', update: 'U', drop: 'D' } }, 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 }, statics: { nextId: 1 }, constructor: function(config) { var me = this; me.data = {}; me.matrices = {}; me.id = Ext.data.Session.nextId++; me.identifierCache = {}; me.recordCreator = me.recordCreator.bind(me); me.mixins.observable.constructor.call(me, 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 = null; record.unjoin(me); } } } me.identifierCache = 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.raise('Record already belongs to an existing session'); } if (record.session !== me) { me.add(record); if (associations) { for (roleName in associations) { associations[roleName].adoptAssociated(record, me); } } } }, commit: function() { var me = this, data = me.data, matrices = me.matrices, dirtyWas = me.getDirty(), entityName, entities, id, record; me.suspendEvent('dirtychange'); for (entityName in data) { entities = data[entityName]; for (id in entities) { record = entities[id].record; if (record) { record.commit(); } } } for (id in matrices) { matrices[id].commit(); } me.clearRecordStates(); me.resumeEvent('dirtychange'); if (me.getDirty() !== dirtyWas) { me.fireDirtyChange(); } }, createRecord: function(type, data, preventAdd) { 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.raise('A parent session already contains an entry for ' + Model.entityName + ': ' + id); } } return new Model(data, preventAdd ? null : 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, wasInstance = type.isModel, record, Model, parent, parentRec; if (wasInstance) { wasInstance = type; id = type.id; type = type.self; } record = me.peekRecord(type, id); if (!record) { Model = type.$isClass ? type : me.getSchema().getEntity(type); parent = me.getParent(); if (parent) { parentRec = parent.peekRecord(Model, id); } if (parentRec) { if (parentRec.isLoading()) { wasInstance = false; } else { record = parentRec.copy(undefined, me); record.$source = parentRec; } } if (!record) { if (wasInstance) { record = wasInstance; me.adopt(record); } 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.raise('Unable to read association entity: ' + this.getModelIdentifier(entityType, id)); }, onInvalidEntityCreate: function(entityType, id) { Ext.raise('Cannot create, record already not exists: ' + this.getModelIdentifier(entityType, id)); }, onInvalidEntityDrop: function(entityType, id) { Ext.raise('Cannot drop, record does not exist: ' + this.getModelIdentifier(entityType, id)); }, onInvalidEntityRead: function(entityType, id) { Ext.raise('Cannot read, record already not exists: ' + this.getModelIdentifier(entityType, id)); }, onInvalidEntityUpdate: function(entityType, id, dropped) { if (dropped) { Ext.raise('Cannot update, record dropped: ' + this.getModelIdentifier(entityType, id)); } else { Ext.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() { var me = this, parent = me.getParent(), visitor; if (parent) { visitor = new Ext.data.session.ChildChangesVisitor(me); me.visitData(visitor); parent.update(visitor.result); me.commit(); } else { Ext.raise('Cannot commit session, no parent exists'); } }, 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, dirtyWas = me.getDirty(), entityName, entityType, entityInfo, i, operation, item, associations, key, role, associationData; me.suspendEvent('dirtychange'); me.getSchema().processKeyChecks(true); for (entityName in data) { entityType = schema.getEntity(entityName); if (!entityType) { Ext.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.raise('Invalid association key for ' + entityName + ', "' + key + '"'); } associationData = entityInfo[role.role]; role.processUpdate(me, associationData); } } me.resumeEvent('dirtychange'); if (me.getDirty() !== dirtyWas) { me.fireDirtyChange(); } }, afterCommit: function(record) { this.trackRecordState(record); }, afterDrop: function(record) { this.trackRecordState(record); }, afterEdit: function(record) { this.trackRecordState(record); }, afterErase: function(record) { this.evict(record); }, afterReject: function(record) { this.trackRecordState(record); }, privates: { add: function(record) { var me = this, id = record.id, entry = me.getEntry(record.self, id), associations, roleName; if (entry.record) { Ext.raise('Duplicate id ' + record.id + ' for ' + record.entityName); } record.session = me; entry.record = record; me.trackRecordState(record, true); me.registerReferences(record); associations = record.associations; for (roleName in associations) { associations[roleName].checkMembership(me, record); } }, applySchema: function(schema) { return Ext.data.schema.Schema.get(schema); }, checkModelType: function(name) { if (name.$isClass) { name = name.entityName; } if (!name) { Ext.raise('Unable to use anonymous models in a Session'); } else if (!this.getSchema().getEntity(name)) { Ext.raise('Unknown entity type ' + name); } }, createEntities: function(entityType, items) { var me = this, len = items.length, i, data, rec, id; for (i = 0; i < len; ++i) { data = items[i]; id = entityType.getIdFromData(data); rec = me.peekRecord(entityType, id); if (!rec) { rec = me.createRecord(entityType, data, true); rec.phantom = true; rec.crudState = 'C'; me.add(rec); rec.crudStateWas = 'C'; } else { me.onInvalidEntityCreate(entityType, id); } } }, 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 me = this, entityName = record.entityName, entities = me.data[entityName], id = record.id; if (entities && entities[id]) { me.untrackRecordState(record); record.unjoin(me); 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.getId() || entityType.entityName; ret = cache[key]; if (!ret) { if (identifier.clone) { ret = identifier.clone({ id: null }); } 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, matrices = me.matrices, 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, key; if (bucket[newId]) { Ext.raise('Cannot change ' + entityName + ' id from ' + oldId + ' to ' + newId + ' id already exists'); } delete bucket[oldId]; bucket[newId] = entry; for (key in matrices) { matrices[key].updateId(record, oldId, newId); } if (refs) { for (roleName in refs) { roleRefs = refs[roleName]; role = associations[roleName]; association = role.association; if (!association.isManyToMany) { 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 me = this, len = items.length, i, data, rec, id; for (i = 0; i < len; ++i) { data = items[i]; id = entityType.getIdFromData(data); rec = me.peekRecord(entityType, id); if (!rec) { rec = me.createRecord(entityType, data, true); } else { me.onInvalidEntityRead(entityType, id); } rec.phantom = false; me.add(rec); } }, 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); record.mergeData(data); } 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.destroyed) { scheduler.remove(me); } me.scheduler = null; me.schedule = me.react = Ext.emptyFn; me.callParent(); }, 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.destroyed) { scheduler.unscheduleItem(me); } me.scheduled = false; } }, sort: function() {} } }); Ext.define('Ext.app.bind.BaseBinding', { extend: Ext.util.Schedulable, isBinding: true, 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.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; if (owner) { owner.onBindDestroy(me); } me.callParent(); me.scope = me.callback = me.owner = null; }, isReadOnly: function() { return true; }, 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 || me.valueChanged(value, previous)) { ++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(); } } }, valueChanged: function(value, previous) { var ret = true; if (previous !== value) { if (value && previous && value instanceof Date && previous instanceof Date) { ret = value.getTime() !== previous.getTime(); } } else { ret = Ext.isArray(value); } return ret; } } }); 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.isAvailable() && !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; return stub && stub.getValue(); }, isAvailable: function() { var stub = this.stub; return stub && stub.isAvailable(); }, isLoading: function() { var stub = this.stub; return stub && stub.isLoading(); }, isReadOnly: function() { var stub = this.stub, options = this.options, ret = true; if (!(options && options.twoWay === false)) { if (stub) { ret = stub.isReadOnly(); } } return ret; }, refresh: function() {}, setValue: function(value) { if (this.isReadOnly()) { Ext.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; return stub && stub.getRawValue(); }, 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, 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(); } if (me.scheduled) { me.unschedule(); } me.callParent(); }, 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.isAvailable() ? this.getRawValue() : null; }, 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; }, isAvailable: function() { return true; }, isLoading: function() { 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, isStub: true, dirty: true, formula: null, validationKey: 'validation', 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.checkHadValue(); } me.path = path; }, destroy: function() { var me = this, formula = me.formula, storeBinding = me.storeBinding; if (formula) { formula.destroy(); } if (storeBinding) { storeBinding.destroy(); } me.detachBound(); 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, value, this); } else { callback.call(scope, field, value, 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, bindMappings = me.bindMappings, storeMappings = bindMappings.store, modelMappings = bindMappings.model, ret; if (!parentData && !Ext.isString(parentData)) { ret = me.hadValue ? null : undefined; } else { ret = me.inspectValue(parentData); if (!ret) { if (parentData.isEntity) { if (modelMappings[name]) { ret = parentData[modelMappings[name]](); } else { ret = parentData.data[name]; } } else if (parentData.isStore && storeMappings[name]) { ret = parentData[storeMappings[name]](); } else { ret = parentData[name]; if (ret === undefined && me.hadValue) { ret = null; } } } } return ret; }, getDataObject: function() { var me = this, parentData = me.parent.getDataObject(), name = me.name, ret = parentData ? parentData[name] : null, storeMappings = me.bindMappings.store, associations; if (!ret) { if (parentData && parentData.isEntity) { associations = parentData.associations; if (associations && name in associations) { ret = parentData[associations[name].getterName](); } } } else if (parentData.isStore && name in storeMappings) { ret = parentData[storeMappings[name]](); } if (!ret || !(ret.$className || Ext.isObject(ret))) { parentData[name] = ret = {}; me.hadValue = 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, ret; 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; replacement.checkHadValue(); ret = me.callParent([ replacement ]); ret.invalidate(true, true); return ret; }, isAvailable: function() { return this.checkAvailability(); }, isLoading: function() { return !this.checkAvailability(true); }, invalidate: function(deep, dirtyOnly) { var me = this, children = me.children, name; me.dirty = true; me.checkHadValue(); if (!dirtyOnly && me.isAvailable()) { 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, preventClimb) { var me = this, parent = me.parent, name = me.name, formula = me.formula, parentData, associations, association, formulaStub, setterName; 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.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]; setterName = association.setterName; if (setterName) { parentData[setterName](value); } me.invalidate(true); } else { parentData.set(name, value); } } else if ((value && value.constructor === Object) || !(value === parentData[name] && parentData.hasOwnProperty(name))) { if (preventClimb || !me.setByLink(value)) { if (value === undefined) { delete parentData[name]; } else { parentData[name] = value; } me.inspectValue(parentData); me.invalidate(true); } } }, onStoreDataChanged: 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, bindMappings = this.bindMappings.model, key, i, child, name, ref; if (children) { if (len) { for (i = 0; i < len; ++i) { name = modifiedFieldNames[i]; child = children[name]; if (!child) { ref = record.fieldsMap[name]; ref = ref && ref.reference; child = ref && children[ref.role]; } if (child) { child.invalidate(true); } } } else { for (key in children) { if (!(associations && key in associations)) { children[key].invalidate(true); } } } for (key in bindMappings) { child = children[key]; if (child) { child.invalidate(); } } } this.invalidate(); }, afterReject: function(record) { this.afterEdit(record, null); }, afterAssociatedRecordSet: function(record, associated, role) { var children = this.children, key = role.role; if (children && key in children) { children[key].invalidate(true); } }, setByLink: function(value) { var me = this, n = 0, ret = false, i, link, path, stub, root, name; 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; } stub = null; if (link) { root = link.parent; name = link.name; if (!root.shouldClimb(name)) { stub = root.insertChild(name); } else { stub = link.getTargetStub(); } } if (stub) { if (path) { stub = stub.descend(path); } stub.set(value); ret = true; } return ret; }, 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(); } } } this.callParent(); }, privates: { bindMappings: { store: { count: 'getCount', first: 'first', last: 'last', loading: 'hasPendingLoad', totalCount: 'getTotalCount' }, model: { dirty: 'isDirty', phantom: 'isPhantom', valid: 'isValid' } }, checkAvailability: function(isLoading) { var me = this, parent = me.parent, bindMappings = me.bindMappings, name = me.name, available = !!(parent && parent.checkAvailability(isLoading)), associations, parentValue, value, availableSet, loading; if (available) { parentValue = me.getParentValue(); value = me.inspectValue(parentValue); if (value) { if (isLoading) { available = !value.hasPendingLoad(); } else { if (value.isStore) { available = true; } else { available = !value.isLoading() || value.loadCount > 0; } } } else { if (parentValue) { if (parentValue.isModel) { if (bindMappings.model[name]) { available = !parent.isLoading(); availableSet = true; } else { associations = parentValue.associations; if (!(associations && name in associations)) { available = true; availableSet = true; } } } else if (parentValue.isStore && bindMappings.store[name] && name !== 'loading') { available = !parent.isLoading(); availableSet = true; } } if (!availableSet) { available = me.hadValue || me.getRawValue() !== undefined; } } } return available; }, checkHadValue: function() { if (!this.hadValue) { this.hadValue = this.getRawValue() !== undefined; } }, 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](); } 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 && boundValue.autoLoad !== false && !boundValue.complete && !boundValue.hasPendingLoad()) { boundValue.load(); } boundValue.on({ scope: me, beginload: 'onStoreDataChanged', load: 'onStoreDataChanged', datachanged: 'onStoreDataChanged', destroy: 'onDestroyBound' }); } } me.boundValue = boundValue; } return boundValue; }, detachBound: function() { var me = this, current = me.boundValue; if (current && !current.destroyed) { if (current.isModel) { current.unjoin(me); } else { current.un({ scope: me, beginload: 'onStoreDataChanged', load: 'onStoreDataChanged', datachanged: 'onStoreDataChanged', destroy: 'onDestroyBound' }); } } }, onDestroyBound: function() { if (!this.owner.destroying) { this.set(null); } }, 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, root = this.parent, name = this.name, rootData, ret; if (root.isRootStub && !root.shouldClimb(name)) { rootData = root.owner.getData(); if (!rootData.hasOwnProperty(name)) { rootData[name] = ret = {}; } } else { ret = binding && binding.getDataObject(); } return ret; }, 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; }, isAvailable: function() { var binding = this.binding; return binding ? binding.isAvailable() : false; }, 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, 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, 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; }, set: function(value, preventClimb) { if (!value || value.constructor !== Object) { Ext.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(), stub, v, key, setSelf, created; for (key in value) { if (key.indexOf('.') >= 0) { Ext.raise('Value names cannot contain dots'); } v = value[key]; if (v !== undefined) { stub = children[key]; setSelf = preventClimb || !me.shouldClimb(key); if (!stub) { stub = me.createRootChild(key, setSelf); created = true; } else if (setSelf && stub.isLinkStub && !stub.getLinkFormulaStub()) { stub = me.insertChild(key); } if (!created || !data.hasOwnProperty(value)) { owner.invalidateChildLinks(key); } stub.set(v, setSelf); } else if (data.hasOwnProperty(key)) { delete data[key]; stub = children[key]; if (stub) { if (!stub.isLinkStub && parentVM) { stub = me.createRootChild(key); } owner.invalidateChildLinks(key, true); stub.invalidate(true); } } } }, schedule: Ext.emptyFn, unschedule: Ext.emptyFn, privates: { checkAvailability: function() { return true; }, insertChild: function(name) { return this.createRootChild(name, true); }, invalidateChildLink: function(name, clear) { var children = this.children, stub = children && children[name]; if (stub && stub.isLinkStub && !stub.getLinkFormulaStub()) { stub = this.createRootChild(name); if (clear) { stub.invalidate(true); } this.owner.invalidateChildLinks(name, clear); } }, shouldClimb: function(name) { var parent = this.owner.getParent(); while (parent) { if (parent.getData().hasOwnProperty(name)) { return true; } parent = parent.getParent(); } return false; } } }); 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; }, isAvailable: function() { for (var bindings = this.bindings, n = bindings.length; n-- > 0; ) { if (bindings[n].isAvailable()) { 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, 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_]' + Ext.String.escapeRegex(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, fnKeywordArgumentNamesRe: /^function\s*[^\(]*\(\s*([^,\)\s]+)/, fnKeywordRe: /^\s*function/, replaceParenRe: /[\(\)]/g, 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.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 = Ext.Function.toCode(formula), defaultProp = 'get', expressions = { $literal: true }, match, getterProp, formulaRe, expr; if (this.fnKeywordRe.test(str)) { match = this.fnKeywordArgumentNamesRe.exec(str); if (match) { getterProp = match[1]; } } else { match = str.split('=>')[0]; if (match) { match = Ext.String.trim(match.replace(this.replaceParenRe, '')).split(','); getterProp = match[0]; } } getterProp = getterProp || defaultProp; 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.util.Fly', { inheritableStatics: { flyPoolSize: 2, fly: function() { var T = this, flyweights = T.flyweights || (T.flyweights = []), instance = flyweights.length ? flyweights.pop() : new T(); instance.reset.apply(instance, arguments); return instance; } }, release: function() { var me = this, T = me.self, flyweights = T.flyweights || (T.flyweights = []); me.reset(); if (flyweights.length < T.flyPoolSize) { flyweights.push(me); } }, reset: Ext.emptyFn }); Ext.define('Ext.parse.Tokenizer', function(Tokenizer) { var flyweights = (Tokenizer.flyweights = []), BOOLEAN = { literal: true, "boolean": true }, ERROR = { error: true }, IDENT = { ident: true }, LITERAL = { literal: true }, NULL = { literal: true, nil: true }, NUMBER = { literal: true, number: true }, STRING = { literal: true, string: true }; return { extend: Ext.util.Fly, isTokenizer: true, statics: { BOOLEAN: BOOLEAN, ERROR: ERROR, IDENT: IDENT, LITERAL: LITERAL, NULL: NULL, NUMBER: NUMBER, STRING: STRING }, config: { keywords: { 'null': { type: 'literal', is: NULL, value: null }, 'false': { type: 'literal', is: BOOLEAN, value: false }, 'true': { type: 'literal', is: BOOLEAN, value: true } }, operators: { '+': 'plus', '-': 'minus', '*': 'multiply', '/': 'divide', '!': 'bang', ',': 'comma', ':': 'colon', '[': 'arrayOpen', ']': 'arrayClose', '{': 'curlyOpen', '}': 'curlyClose', '(': 'parenOpen', ')': 'parenClose' } }, error: null, index: -1, constructor: function(config) { this.operators = {}; this.initConfig(config); }, next: function() { var token = this.peek(); this.head = undefined; return token; }, peek: function() { var me = this, error = me.error, token = me.head; if (error) { return error; } if (token === undefined) { me.head = token = me.advance(); } return token; }, release: function() { this.reset(); if (flyweights.length < Tokenizer.flyPoolSize) { flyweights.push(this); } }, reset: function(text, pos, end) { var me = this; me.error = null; me.head = undefined; me.index = -1; me.text = text || null; me.pos = pos || 0; me.end = (text && end == null) ? text.length : end; return me; }, privates: { digitRe: /[0-9]/, identFirstRe: /[a-z_$]/i, identRe: /[0-9a-z_$]/i, spaceRe: /[ \t]/, end: 0, head: undefined, pos: 0, text: null, applyOperators: function(ops) { var operators = this.operators, block, c, def, i, len, name, op; for (op in ops) { block = operators; name = ops[op]; len = op.length; for (i = 0; i < len; ++i) { c = op.charAt(i); block = block[c] || (block[c] = {}); } if (name) { block.token = def = { type: 'operator', value: op, is: { operator: true } }; def.is[name] = true; } else { block.token = null; } } }, advance: function() { var me = this, spaceRe = me.spaceRe, text = me.text, length = me.end, c; while (me.pos < length) { c = text.charAt(me.pos); if (spaceRe.test(c)) { ++me.pos; continue; } me.index = me.pos; return me.parse(c); } return null; }, parse: function(c) { var me = this, digitRe = me.digitRe, text = me.text, length = me.end, ret; if (c === '.' && me.pos + 1 < length) { if (digitRe.test(text.charAt(me.pos + 1))) { ret = me.parseNumber(); } } if (!ret && me.operators[c]) { ret = me.parseOperator(c); } if (!ret) { if (c === '"' || c === "'") { ret = me.parseString(); } else if (digitRe.test(c)) { ret = me.parseNumber(); } else if (me.identFirstRe.test(c)) { ret = me.parseIdent(); } else { ret = me.syntaxError('Unexpected character'); } } return ret; }, parseIdent: function() { var me = this, identRe = me.identRe, keywords = me.getKeywords(), includeDots = !me.operators['.'], text = me.text, start = me.pos, end = start, length = me.end, prev = 0, c, value; while (end < length) { c = text.charAt(end); if (includeDots && c === '.') { if (prev === '.') { return me.syntaxError(end, 'Unexpected dot operator'); } ++end; } else if (identRe.test(c)) { ++end; } else { break; } prev = c; } if (prev === '.') { return me.syntaxError(end - 1, 'Unexpected dot operator'); } value = text.substring(start, me.pos = end); return (keywords && keywords[value]) || { type: 'ident', is: IDENT, value: value }; }, parseNumber: function() { var me = this, digitRe = me.digitRe, text = me.text, start = me.pos, length = me.end, c, decimal, exp, token; while (me.pos < length) { c = text.charAt(me.pos); if (c === '-' || c === '+') { if (me.pos !== start) { return me.syntaxError(start, 'Invalid number'); } ++me.pos; } else if (c === '.') { if (decimal) { break; } decimal = true; ++me.pos; } else if (c === 'e' || c === 'E') { if (exp) { break; } decimal = exp = true; c = text.charAt(++me.pos); if (c === '-' || c === '+') { ++me.pos; } } else if (digitRe.test(c)) { ++me.pos; } else { break; } } token = { type: 'literal', is: NUMBER, value: +text.substring(start, me.pos) }; if (!isFinite(token.value)) { token = me.syntaxError(start, 'Invalid number'); } return token; }, parseOperator: function(c) { var me = this, block = me.operators, text = me.text, length = me.end, end = me.pos, match, matchEnd, token; while (block[c]) { block = block[c]; token = block.token; ++end; if (token) { match = token; matchEnd = end; } if (end < length) { c = text.charAt(end); } else { break; } } if (match) { me.pos = matchEnd; } return match; }, parseString: function() { var me = this, text = me.text, pos = me.pos, start = pos, length = me.end, str = '', c, closed, quote; quote = text.charAt(pos++); while (pos < length) { c = text.charAt(pos++); if (c === quote) { closed = true; break; } if (c === '\\' && pos < length) { c = text.charAt(pos++); } str += c; } me.pos = pos; if (!closed) { return me.syntaxError(start, 'Unterminated string'); } return { type: 'literal', is: STRING, value: str }; }, syntaxError: function(at, message) { if (typeof at === 'string') { message = at; at = this.pos; } var suffix = (at == null) ? '' : (' (at index ' + at + ')'), error = new Error(message + suffix); error.type = 'error'; error.is = ERROR; if (suffix) { error.at = at; } return this.error = error; } } }; }); Ext.define('Ext.parse.Symbol', { priority: 0, constructor: function(id, config) { var me = this, defaultProperty = me.defaultProperty; if (config && typeof config === 'object') { Ext.apply(me, config); } else if (config !== undefined && defaultProperty) { me[defaultProperty] = config; } me.id = id; }, dump: function() { var me = this, ret = { at: me.at, arity: me.arity }, i; if ('value' in me) { ret.value = me.value; } if (me.lhs) { ret.lhs = me.lhs.dump(); ret.rhs = me.rhs.dump(); } if (me.operand) { ret.operand = me.operand.dump(); } if (me.args) { ret.args = []; for (i = 0; i < me.args.length; ++i) { ret.args.push(me.args[i].dump()); } } return ret; }, led: function() { this.parser.syntaxError(this.at, 'Missing operator'); }, nud: function() { this.parser.syntaxError(this.at, 'Undefined'); }, update: function(config) { if (config && typeof config === 'object') { var me = this, priority = config.priority, led = config.led, nud = config.nud; if (me.priority <= priority) { me.priority = priority; } if (led) { me.led = led; } if (nud) { me.nud = nud; } } } }); Ext.define('Ext.parse.symbol.Constant', { extend: Ext.parse.Symbol, arity: 'literal', isLiteral: true, defaultProperty: 'value', constructor: function(id, config) { this.callParent([ id, config ]); this._value = this.value; }, nud: function() { var me = this; me.value = me._value; me.arity = 'literal'; me.isLiteral = true; return me; } }); Ext.define('Ext.parse.symbol.Infix', { extend: Ext.parse.Symbol, arity: 'binary', isBinary: true, defaultProperty: 'priority', led: function(left) { var me = this; me.lhs = left; me.rhs = me.parser.parseExpression(me.priority); me.arity = 'binary'; me.isBinary = true; return me; } }); Ext.define('Ext.parse.symbol.InfixRight', { extend: Ext.parse.symbol.Infix, led: function(left) { var me = this; me.lhs = left; me.rhs = me.parser.parseExpression(me.priority - 1); me.arity = 'binary'; me.isBinary = true; return me; } }); Ext.define('Ext.parse.symbol.Paren', { extend: Ext.parse.Symbol, arity: 'binary', isBinary: true, priority: 80, led: function(left) { var me = this, args = [], parser = me.parser, id = left.id, type = left.arity; if (id !== '.' && id !== '[') { if ((type !== "unary" || id !== "function") && type !== "ident" && id !== "(" && id !== "&&" && id !== "||" && id !== "?") { parser.syntaxError(left.at, "Expected a variable name."); } } me.arity = 'invoke'; me.isInvoke = true; me.operand = left; me.args = args; while (parser.token.id !== ')') { if (args.length) { parser.advance(','); } args.push(parser.parseExpression()); } parser.advance(')'); return me; }, nud: function() { var parser = this.parser, ret = parser.parseExpression(); parser.advance(")"); return ret; } }); Ext.define('Ext.parse.symbol.Prefix', { extend: Ext.parse.Symbol, arity: 'unary', isUnary: true, priority: 70, nud: function() { var me = this; me.operand = me.parser.parseExpression(me.priority); me.arity = 'unary'; me.isUnary = true; return me; } }); Ext.define('Ext.parse.Parser', function() { var ITSELF = function() { return this; }; return { extend: Ext.util.Fly, isParser: true, config: { constants: { 'null': null, 'false': false, 'true': true }, infix: { '+': 50, '-': 50, '*': 60, '/': 60 }, infixRight: { '&&': 30, '||': 30 }, prefix: { '!': 0, '-': 0, '+': 0 }, symbols: { ':': 0, ',': 0, ')': 0, '[': 0, ']': 0, '{': 0, '}': 0, '(end)': 0, '(ident)': { arity: 'ident', isIdent: true, nud: ITSELF }, '(literal)': { arity: 'literal', isLiteral: true, nud: ITSELF }, '(': { xclass: 'Ext.parse.symbol.Paren' } }, tokenizer: { keywords: null } }, token: null, constructor: function(config) { this.symbols = {}; this.initConfig(config); }, advance: function(expected) { var me = this, tokenizer = me.tokenizer, token = tokenizer.peek(), symbols = me.symbols, index = tokenizer.index, is, symbol, value; if (me.error) { throw me.error; } if (expected) { me.expect(expected); } if (!token) { return me.token = symbols['(end)']; } tokenizer.next(); is = token.is; value = token.value; if (is.ident) { symbol = symbols[value] || symbols['(ident)']; } else if (is.operator) { if (!(symbol = symbols[value])) { me.syntaxError(token.at, 'Unknown operator "' + value + '"'); } } else if (is.literal) { symbol = symbols['(literal)']; } else { me.syntaxError(token.at, 'Unexpected token'); } me.token = symbol = Ext.Object.chain(symbol); symbol.at = index; symbol.value = value; if (!symbol.arity) { symbol.arity = token.type; } return symbol; }, expect: function(expected) { var token = this.token; if (expected !== token.id) { this.syntaxError(token.at, 'Expected "' + expected + '"'); } return this; }, parseExpression: function(rightPriority) { var me = this, token = me.token, left; rightPriority = rightPriority || 0; me.advance(); left = token.nud(); while (rightPriority < (token = me.token).priority) { me.advance(); left = token.led(left); } return left; }, reset: function(text, pos, end) { var me = this; me.error = me.token = null; me.tokenizer.reset(text, pos, end); me.advance(); return me; }, syntaxError: function(at, message) { if (typeof at === 'string') { message = at; at = this.pos; } var suffix = (at == null) ? '' : (' (at index ' + at + ')'), error = new Error(message + suffix); error.type = 'error'; if (suffix) { error.at = at; } throw this.error = error; }, privates: { error: null, addSymbol: function(id, config, type, update) { var symbols = this.symbols, symbol = symbols[id], cfg, length, i; if (symbol) { if (typeof config === 'object') { cfg = config; } else if (update && type) { update = Ext.Array.from(update); length = update.length; cfg = {}; for (i = 0; i < length; i++) { cfg[update[i]] = type.prototype[update[i]]; } } else { return symbol; } symbol.update(cfg); } else { if (config && config.xclass) { type = Ext.ClassManager.get(config.xclass); } else { type = type || Ext.parse.Symbol; } symbols[id] = symbol = new type(id, config); symbol.parser = this; } return symbol; }, addSymbols: function(symbols, type, update) { for (var id in symbols) { this.addSymbol(id, symbols[id], type, update); } }, applyConstants: function(constants) { this.addSymbols(constants, Ext.parse.symbol.Constant, 'nud'); }, applyInfix: function(operators) { this.addSymbols(operators, Ext.parse.symbol.Infix, 'led'); }, applyInfixRight: function(operators) { this.addSymbols(operators, Ext.parse.symbol.InfixRight, 'led'); }, applyPrefix: function(operators) { this.addSymbols(operators, Ext.parse.symbol.Prefix, 'nud'); }, applySymbols: function(symbols) { this.addSymbols(symbols); }, applyTokenizer: function(config) { var ret = config; if (config && !config.isTokenizer) { ret = new Ext.parse.Tokenizer(config); } this.tokenizer = ret; } } }; }); Ext.define('Ext.app.bind.Parser', { extend: Ext.parse.Parser, infix: { ':': { priority: 70, dump: function() { var me = this, ret = { at: me.at, arity: me.arity, value: me.value, operand: me.operand.dump(), fmt: [] }, fmt = me.fmt, i; for (i = 0; i < fmt.length; ++i) { ret.fmt.push(fmt[i].dump()); } return ret; }, led: function(left) { var me = this; me.arity = 'formatter'; me.operand = left; me.fmt = me.parser.parseFmt(); return me; } }, '?': { priority: 20, led: function(left) { var me = this, parser = me.parser, symbol = parser.symbols[':'], temp; me.condition = left; temp = symbol.priority; symbol.priority = 0; me.tv = parser.parseExpression(0); me.parser.advance(':'); symbol.priority = temp; me.fv = parser.parseExpression(0); me.arity = 'ternary'; return me; } }, '===': 40, '!==': 40, '==': 40, '!=': 40, '<': 40, '<=': 40, '>': 40, '>=': 40 }, symbols: { '(': { nud: function() { var parser = this.parser, symbol = parser.symbols[':'], ret, temp; temp = symbol.priority; symbol.priority = 70; ret = parser.parseExpression(); parser.advance(")"); symbol.priority = temp; return ret; } } }, prefix: { '@': 0 }, tokenizer: { operators: { '@': 'at', '?': 'qmark', '===': 'feq', '!==': 'fneq', '==': 'eq', '!=': 'neq', '<': 'lt', '<=': 'lte', '>': 'gt', '>=': 'gte', '&&': 'and', '||': 'or' } }, compileExpression: function(tokens, tokensMaps) { var me = this, debug, fn; me.tokens = tokens; me.tokensMap = tokensMaps; debug = me.token.value === '@' && me.tokenizer.peek(); if (debug) { debug = debug.value === 'debugger'; if (debug) { me.advance(); me.advance(); } } fn = me.parseSlot(me.parseExpression(), debug); me.tokens = me.tokensMap = null; return fn; }, compileFormat: function() { var fn; try { fn = this.parseSlot({ arity: 'formatter', fmt: this.parseFmt(), operand: { arity: 'ident', value: 'dummy' } }); this.expect('(end)'); } catch (e) { Ext.raise('Invalid format expression: "' + this.tokenizer.text + '"'); } return fn; }, privates: { useEval: Ext.isGecko, escapeRe: /("|'|\\)/g, parseFmt: function() { var me = this, fmt = [], priority = me.symbols[':'].priority, expr; do { if (fmt.length) { me.advance(); } expr = me.parseExpression(priority); if (expr.isIdent || expr.isInvoke) { fmt.push(expr); } else { me.syntaxError(expr.at, 'Expected formatter name'); } } while (me.token.id === ':'); return fmt; }, parseSlot: function(expr, debug) { var me = this, defs = [], body = [], tokens = me.tokens || [], fn, code, i, length, temp; me.definitions = defs; me.body = body; body.push('return ' + me.compile(expr) + ';'); length = tokens.length; code = 'var fm = Ext.util.Format,\nme,'; temp = 'var a = Ext.Array.from(values);\nme = scope;\n'; if (tokens.length) { for (i = 0; i < length; i++) { code += 'v' + i + ((i == length - 1) ? ';' : ','); temp += 'v' + i + ' = a[' + i + ']; '; } } else { code += 'v0;'; temp += 'v0 = a[0];'; } defs = Ext.Array.insert(defs, 0, [ code ]); body = Ext.Array.insert(body, 0, [ temp ]); body = body.join('\n'); if (debug) { body = 'debugger;\n' + body; } defs.push((me.useEval ? '$=' : 'return') + ' function (values, scope) {', body, '}'); code = defs.join('\n'); fn = me.useEval ? me.evalFn(code) : (new Function('Ext', code))(Ext); me.definitions = me.body = null; return fn; }, compile: function(expr) { var me = this, v; switch (expr.arity) { case 'ident': return me.addToken(expr.value); case 'literal': v = expr.value; return (typeof v === 'string') ? '"' + String(v).replace(me.escapeRe, '\\$1') + '"' : v; case 'unary': return me.compileUnary(expr); case 'binary': return me.compileBinary(expr); case 'ternary': return me.compileTernary(expr); case 'formatter': return me.compileFormatter(expr); } return this.syntaxError(expr.at, 'Compile error! Unknown symbol'); }, compileUnary: function(expr) { var v = expr.value, op = expr.operand; if (v === '!' || v === '-' || v === '+') { return v + '(' + this.compile(op) + ')'; } else if (v === '@') { if (!op.isIdent) { return this.syntaxError(expr.at, 'Compile error! Unexpected symbol'); } return op.value; } return ''; }, compileBinary: function(expr) { return '(' + this.compile(expr.lhs) + ' ' + expr.value + ' ' + this.compile(expr.rhs) + ')'; }, compileTernary: function(expr) { return '(' + this.compile(expr.condition) + ' ? ' + this.compile(expr.tv) + ' : ' + this.compile(expr.fv) + ')'; }, compileFormatter: function(expr) { var me = this, fmt = expr.fmt, length = fmt.length, body = [ 'var ret;' ], i; if (fmt.length) { body.push('ret = ' + me.compileFormatFn(fmt[0], me.compile(expr.operand)) + ';'); for (i = 1; i < length; i++) { body.push('ret = ' + me.compileFormatFn(fmt[i], 'ret') + ';'); } } body.push('return ret;'); return me.addFn(body.join('\n')); }, compileFormatFn: function(expr, value) { var fmt, args = [], code = '', length, i; if (expr.isIdent) { fmt = expr.value; } else if (expr.isInvoke) { fmt = expr.operand.value; args = expr.args; } if (fmt.substring(0, 5) === 'this.') { fmt = 'me.' + fmt.substring(5); } else { if (!(fmt in Ext.util.Format)) { return this.syntaxError(expr.at, 'Compile error! Invalid format specified "' + fmt + '"'); } fmt = 'fm.' + fmt; } code += value; length = args.length; for (i = 0; i < length; i++) { code += ', ' + this.compile(args[i]); } return fmt + '(' + code + ')'; }, addFn: function(body) { var defs = this.definitions, name = 'f' + defs.length; defs.push('function ' + name + '() {', body, '}'); return name + '()'; }, evalFn: function($) { eval($); return $; }, addToken: function(token) { var tokensMap = this.tokensMap, tokens = this.tokens, pos = 0; if (tokensMap && tokens) { if (token in tokensMap) { pos = tokensMap[token]; } else { tokensMap[token] = pos = tokens.length; tokens.push(token); } } return 'v' + pos; } } }); Ext.define('Ext.app.bind.Template', { escapes: false, 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; for (i = 0; i < length; ++i) { slot = slots[i]; if (slot) { buffer[i] = slot(values, scope); } } if (slot && me.single) { return buffer[0]; } return buffer.join(''); }, getText: function() { return this.buffer.join(''); }, getTokens: function() { return this.tokens; }, isStatic: function() { var tokens = this.getTokens(), slots = this.slots; return (tokens.length === 0 && slots.length === 0); }, privates: { literalChar: '~', escapeChar: '\\', parse: function() { var me = this, text = me.text, parser = Ext.app.bind.Parser.fly(), buffer = (me.buffer = []), slots = (me.slots = []), length = text.length, pos = 0, escapes = me.escapes, current = '', i = 0, esc = me.escapeChar, lit = me.literalChar, escaped, tokens, tokensMap, lastEscaped, c, prev, key; for (key in me._initters) { delete me[key]; } me.tokens = tokens = []; me.tokensMap = tokensMap = {}; while (i < length) { c = text[i]; lastEscaped = escaped; escaped = escapes && c === esc; if (escaped) { c = text[i + 1]; ++i; } else if (c === lit && prev === lit && !lastEscaped) { current = current.slice(0, -1); current += text.substring(i + 1); break; } else if (c === '{') { if (current) { buffer[pos++] = current; current = ''; } parser.reset(text, i + 1); i = me.parseExpression(parser, pos); ++pos; continue; } current += c; ++i; prev = c; } if (current) { buffer[pos] = current; } parser.release(); me.single = buffer.length === 0 && slots.length === 1; return me; }, parseExpression: function(parser, pos) { var i; this.slots[pos] = parser.compileExpression(this.tokens, this.tokensMap); i = parser.token.at + 1; parser.expect('}'); return i; } } }); Ext.define('Ext.app.bind.TemplateBinding', { extend: Ext.app.bind.BaseBinding, 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 (!tpl.isStatic()) { me.multiBinding = new Ext.app.bind.Multi(tokens, owner, me.onBindData, me); } else { me.isStatic = true; me.onData(tpl.getText()); } }, 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; }, isAvailable: function() { var multi = this.multiBinding; return multi ? multi.isAvailable() : false; }, 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', isChainedStore: true, config: { source: null, remoteFilter: false, remoteSort: false }, mixins: [ Ext.data.LocalStore ], updateRemoteFilter: function(remoteFilter, oldRemoteFilter) { if (remoteFilter) { Ext.raise('Remote filtering cannot be used with chained stores.'); } this.callParent([ remoteFilter, oldRemoteFilter ]); }, updateRemoteSort: function(remoteSort, oldRemoteSort) { if (remoteSort) { Ext.raise('Remote sorting cannot be used with chained stores.'); } this.callParent([ remoteSort, oldRemoteSort ]); }, remove: function() { var source = this.getSource(); if (!source) { Ext.raise('Cannot remove records with no source.'); } return source.remove.apply(source, arguments); }, removeAll: function() { var source = this.getSource(); if (!source) { Ext.raise('Cannot remove records with no source.'); } return source.removeAll(); }, getData: function() { var me = this, data = me.data; if (!data) { me.data = data = me.constructDataCollection(); } return data; }, getTotalCount: function() { return this.getCount(); }, getSession: function() { return this.getSourceValue('getSession', null); }, 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.raise(s); } } return source; }, updateSource: function(source, oldSource) { var me = this, data; if (oldSource && !oldSource.destroyed) { 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.getSourceValue('getModel', null); }, getProxy: function() { return null; }, onCollectionAdd: function(collection, info) { var me = this, records = info.items, lastChunk = !info.next; if (me.ignoreCollectionAdd) { return; } if (me.activeRanges) { me.syncActiveRanges(); } 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); me.fireEvent('datachanged', me); }, onCollectionUpdateKey: function(source, details) { this.fireEvent('idchanged', this, details.item, details.oldKey, details.newKey); }, 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); this.callObservers('BeforeLoad', [ operation ]); }, onSourceAfterLoad: function(source, records, successful, operation) { this.fireEvent('load', this, records, successful, operation); this.callObservers('AfterLoad', [ 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.getSourceValue('hasPendingLoad', false); }, isLoaded: function() { return this.getSourceValue('isLoaded', false); }, isLoading: function() { return this.getSourceValue('isLoading', false); }, doDestroy: function() { var me = this; me.observers = null; me.setSource(null); me.getData().destroy(true); me.data = null; me.callParent(); }, privates: { getSourceValue: function(method, defaultValue) { var source = this.getSource(), val = defaultValue; if (source && !source.destroyed) { val = source[method](); } return val; }, 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 ], alias: 'viewmodel.default', isViewModel: true, factoryConfig: { name: 'viewModel' }, collectTimeout: 100, expressionRe: /^(?:\{(?:(\d+)|([a-z_][\w\.]*))\})$/i, statics: { escape: function(value) { var ret = value, key; if (typeof value === 'string') { ret = '~~' + value; } else if (value && value.constructor === Object) { ret = {}; for (key in value) { ret[key] = this.escape(value[key]); } } return ret; } }, $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.bindings = {}; this.initConfig(config); }, destroy: function() { var me = this, scheduler = me._scheduler, stores = me.storeInfo, parent = me.getParent(), task = me.collectTask, children = me.children, bindings = me.bindings, key, store, autoDestroy, storeBinding; 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]; storeBinding = store.$binding; autoDestroy = store.autoDestroy; if (autoDestroy || (!store.$wasInstance && autoDestroy !== false)) { store.destroy(); } Ext.destroy(storeBinding); } } if (parent) { parent.unregisterChild(me); } me.getRoot().destroy(); for (key in bindings) { bindings[key].destroy(); } if (scheduler && scheduler.$owner === me) { scheduler.$owner = null; scheduler.destroy(); } me.children = me.storeInfo = me._session = me._view = me._scheduler = me.bindings = me._root = me._parent = me.formulaFn = me.$formulaData = null; me.destroying = false; me.callParent(); }, bind: function(descriptor, callback, scope, options) { var me = this, track = true, 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); track = false; } else { binding = new Ext.app.bind.TemplateBinding(descriptor, me, callback, scope, options); } if (track) { me.bindings[binding.id] = binding; } 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, create, id, modelType, linkStub, rec; if (key.indexOf('.') > -1) { Ext.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.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 = me.getRoot().createStubChild(key); stub.set(rec); } else { stub = me.getStub(key); if (!stub.isLinkStub) { linkStub = new Ext.app.bind.LinkStub(me, stub.name); stub.graft(linkStub); stub = linkStub; } stub.link(reference); } }, notify: function() { var scheduler = this.getScheduler(); if (!scheduler.firing) { scheduler.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.raise('Invalid model name: ' + type); } } if (hasId) { record = Model.createWithId(id); record.load(); } else { record = new Model(); } } return record; }, bindExpression: function(descriptor, callback, scope, options) { var stub = this.getStub(descriptor); return stub.bind(callback, scope, options); }, applyScheduler: function(scheduler) { if (scheduler && !scheduler.isInstance) { if (scheduler === true) { scheduler = {}; } if (!('preSort' in scheduler)) { scheduler = Ext.apply({ preSort: 'kind,-depth' }, scheduler); } scheduler = new Ext.util.Scheduler(scheduler); scheduler.$owner = this; } return scheduler; }, getScheduler: function() { var me = this, scheduler = me._scheduler, parent; 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(); }, invalidateChildLinks: function(name, clear) { var children = this.children, key; if (children) { for (key in children) { children[key].getRoot().invalidateChildLink(name, clear); } } }, onBindDestroy: function(binding, fromChild) { var me = this, parent; if (me.destroying) { return; } if (!fromChild) { delete me.bindings[binding.id]; } parent = me.getParent(); if (parent) { parent.onBindDestroy(binding, true); } 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, true); } }, applyParent: function(parent) { if (parent) { parent.registerChild(this); } return parent; }, applyStores: function(stores) { var me = this, root = me.getRoot(), key, cfg, storeBind, stub, listeners; 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.setConfig(cfg); } }, 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; cfg.resolveListenerScope = this.listenerScopeFn; store = Ext.Factory.store(cfg); store.$binding = binding; this.setupStore(store, key); }, setupStore: function(store, key) { var me = this, obj = {}; me.getData(); store.resolveListenerScope = me.listenerScopeFn; me.storeInfo[key] = store; obj[key] = store; me.setData(obj); }, applyFormulas: function(formulas) { var me = this, root = me.getRoot(), name, stub; me.getData(); for (name in formulas) { if (name.indexOf('.') >= 0) { Ext.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, 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, mixins: [ Ext.mixin.Observable ], exceptions: { TRANSPORT: 'xhr', PARSE: 'parse', DATA: 'data', LOGIN: 'login', SERVER: 'exception' }, providerClasses: {}, remotingMethods: {}, config: { varName: 'Ext.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.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; }, resolveApi: function(api, caller) { var prefix, action, method, fullName, fn; prefix = api && api.prefix; if (prefix && prefix.substr(prefix.length - 1) !== '.') { prefix += '.'; } for (action in api) { method = api[action]; if (action !== 'prefix' && typeof method !== 'function') { fullName = (prefix || '') + method; fn = this.parseMethod(fullName); if (typeof fn === 'function') { api[action] = fn; } else { Ext.raise("Cannot resolve Direct API method '" + fullName + "' for " + action + " action in " + caller.$className + " instance with id: " + (caller.id != null ? caller.id : 'unknown')); } } } return api; }, 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.mixin.Observable ], isProvider: true, $configPrefixed: false, $configStrict: false, config: { headers: undefined }, subscribers: 0, constructor: function(config) { var me = this; me.mixins.observable.constructor.call(me, config); me.requests = {}; Ext.applyIf(me, { id: Ext.id(null, 'provider-') }); }, destroy: function() { var me = this; me.disconnect(true); me.callParent(); }, 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 || force) { if (force) { me.subscribers = 0; } else { me.subscribers--; } if (me.subscribers === 0) { me.doDisconnect(); me.fireEventArgs('disconnect', [ me ]); } } }, doDisconnect: function() { var requests = this.requests, request, id; for (id in requests) { request = requests[id]; request.abort(); } this.requests = {}; }, sendAjaxRequest: function(params) { var request = Ext.Ajax.request(params); if (request && request.id) { this.requests[request.id] = request; } return request; }, onData: function(options, success, response) { if (response && response.request) { delete this.requests[response.request.id]; } }, 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, 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([ initial ]); }, updatePageSize: function(value, oldValue) { if (oldValue != null) { throw "pageMap page size may not be changed"; } }, 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.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), storeIndex = (pageNumber - 1) * pageSize, indexMap = me.indexMap, page, i, len, startIdx; 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 != null) { 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.raise('insert operation not suppported into buffered Store'); }, remove: function() { Ext.raise('remove operation not suppported from buffered Store'); }, removeAt: function() { Ext.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 me = this, pageNumber = me.getPageFromRecordIndex(start), endPageNumber = me.getPageFromRecordIndex(end); for (; pageNumber <= endPageNumber; pageNumber++) { if (!me.hasPage(pageNumber)) { return false; } } return (endPageNumber - 1) * me._pageSize + me.getPage(endPageNumber).length > end; }, 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) { if (end) { end--; } if (!this.hasRange(start, end)) { Ext.raise('PageMap asked for range which it does not have'); } var me = this, Array = Ext.Array, 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 = sliceBegin > 0; } else { sliceBegin = 0; doSlice = false; } if (pageNumber === endPageNumber) { sliceEnd = pageSize - (dataEnd - end); doSlice = doSlice || sliceEnd < pageSize; } if (doSlice) { Array.push(result, Array.slice(me.getPage(pageNumber), sliceBegin, sliceEnd)); } else { Array.push(result, me.getPage(pageNumber)); } } return result; } }); Ext.define('Ext.data.BufferedStore', { extend: Ext.data.ProxyStore, alias: 'store.buffered', 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.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; }, applyAutoSort: function() {}, createFiltersCollection: function() { return new Ext.util.FilterCollection(); }, createSortersCollection: function() { return new Ext.util.SorterCollection(); }, updateRemoteFilter: function(remoteFilter, oldRemoteFilter) { if (remoteFilter === false) { Ext.raise('Buffered stores are always remotely filtered.'); } this.callParent([ remoteFilter, oldRemoteFilter ]); }, updateRemoteSort: function(remoteSort, oldRemoteSort) { if (remoteSort === false) { Ext.raise('Buffered stores are always remotely sorted.'); } this.callParent([ remoteSort, oldRemoteSort ]); }, updateTrackRemoved: function(value) { if (value !== false) { Ext.raise('Cannot use trackRemoved with a buffered store.'); } this.callParent(arguments); }, updateGroupField: function(field) { this.group(field); }, 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.raise('add method may not be called on a buffered store - the store is a map of remote data'); }, insert: function() { Ext.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'); } } }, flushLoad: function() { var me = this, options = me.pendingLoadOptions; me.clearLoadTask(); if (!options) { return; } if (!options.preserveOnFlush) { me.getData().clear(); options.page = 1; options.start = 0; options.limit = me.getViewSize() || me.getDefaultViewSize(); } options.loadCallback = options.callback; options.callback = null; 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 (!options) { options = {}; } if (me.loading || me.fireEvent('beforeload', me, options) === false) { return; } waitForReload = function() { var newCount = me.totalCount, oldRequestSize = endIdx - startIdx; if (endIdx >= newCount) { endIdx = newCount - 1; startIdx = Math.max(endIdx - oldRequestSize, 0); } if (me.rangeCached(startIdx, endIdx, false)) { me.loadCount = (me.loadCount || 0) + 1; me.loading = false; data.un('pageadd', waitForReload); records = data.getRange(startIdx, endIdx); me.fireEvent('refresh', me); me.fireEvent('load', me, records, true); } }; bufferZone = Math.ceil((me.getLeadingBufferZone() + me.getTrailingBufferZone()) / 2); if (me.lastRequestStart && me.preserveScrollOnReload) { startIdx = me.lastRequestStart; endIdx = me.lastRequestEnd; lastTotal = me.getTotalCount(); } else { startIdx = options.start || 0; endIdx = startIdx + (options.count || me.getPageSize()) - 1; } data.clear(true); delete me.totalCount; startIdx = Math.max(startIdx - bufferZone, 0); endIdx = Math.min(endIdx + bufferZone, lastTotal); startIdx = startIdx === 0 ? 0 : startIdx - 1; endIdx = endIdx === lastTotal ? endIdx : endIdx + 1; startPage = me.getPageFromRecordIndex(startIdx); endPage = me.getPageFromRecordIndex(endIdx); me.loading = true; options.waitForReload = waitForReload; data.on('pageadd', waitForReload); for (i = startPage; i <= endPage; i++) { me.prefetchPage(i, options); } }, filter: function() { if (!this.getRemoteFilter()) { Ext.raise('Local filtering may not be used on a buffered store - the store is a map of remote data'); } this.callParent(arguments); }, filterBy: function(fn, scope) { Ext.raise('Local filtering may not be used on a buffered store - the store is a map of remote data'); }, loadData: function(data, append) { Ext.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; options.callback = null; options.preserveOnFlush = true; return me.load(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; if (options.forRender !== false) { requiredStart = start === 0 ? 0 : start - 1; requiredEnd = end === maxIndex ? end : end + 1; } else { requiredStart = start; requiredEnd = end; } me.lastRequestStart = start; me.lastRequestEnd = end; if (me.rangeCached(start, end, options.forRender)) { 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(start, end)) { 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); }, contains: function(record) { return this.indexOf(record) > -1; }, 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 && direction !== undefined) { oldGrouper.setDirection(direction); } else { me.grouper = new Ext.util.Grouper({ property: grouper, direction: direction || 'ASC', root: 'data' }); } } else { me.grouper = grouper ? me.getSorters().decodeSorter(grouper, Ext.util.Grouper) : null; } 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.loadCount = (me.loadCount || 0) + 1; 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.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 { me.loading = false; 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, existingPageRequest; if (pageSize) { if (me.lastPageSize && pageSize != me.lastPageSize) { Ext.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; } existingPageRequest = me.pageRequests[options.page]; if (!existingPageRequest || existingPageRequest.getOperation().pageMapGeneration !== data.pageMapGeneration) { 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(), 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)) { reqs[page].getOperation().abort(); } } 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) { if (this.destroying || this.destroyed) { return; } var me = this, resultSet = operation.getResultSet(), records = operation.getRecords(), successful = operation.wasSuccessful(), page = operation.getPage(), waitForReload = operation.waitForReload, oldTotal = me.totalCount, requests = me.pageRequests, key, op; 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) { if (me.totalCount === 0) { if (waitForReload) { for (key in requests) { op = requests[key].getOperation(); if (op.waitForReload === waitForReload) { delete op.waitForReload; } } me.getData().un('pageadd', waitForReload); me.fireEvent('refresh', me); me.fireEvent('load', me, [], true); } } else { 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, forRender) { var requiredStart = start, requiredEnd = end; if (forRender !== false) { requiredStart = start === 0 ? 0 : start - 1 , requiredEnd = end === this.totalCount - 1 ? end : end + 1; } return this.getData().hasRange(requiredStart, requiredEnd); }, 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.fireEvent('beforesort', me, sorters); me.clearAndLoad({ callback: function() { me.fireEvent('sort', me, sorters); } }); } else { me.fireEvent('sort', me, sorters); } }, clearAndLoad: function(options) { var me = this; me.clearing = true; me.getData().clear(); me.clearing = false; me.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', config: { paramOrder: undefined, paramsAsHash: true, directFn: undefined, api: undefined, metadata: undefined }, paramOrderRe: /[\s,|]/, constructor: function(config) { this.callParent([ config ]); this.canceledOperations = {}; }, 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(), method; if (fn) { me.setDirectFn(method = Ext.direct.Manager.parseMethod(fn)); if (!Ext.isFunction(method)) { Ext.raise('Cannot resolve directFn ' + fn); } } if (api) { api = Ext.direct.Manager.resolveApi(api, me); me.setApi(api); } 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 || !fn.directCfg) { Ext.raise({ msg: 'No Ext Direct function specified for Direct proxy "' + action + '" operation', proxy: me }); } if (!me.paramOrder && fn.directCfg.method.len > 1) { Ext.raise({ msg: 'Incorrect parameters for Direct proxy "' + action + '" operation', proxy: me }); } 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, allowSingle: writer.getAllowSingle(), paramOrder: me.getParamOrder(), paramsAsHash: me.getParamsAsHash(), paramsAsArray: true, metadata: me.getMetadata(), callback: me.createRequestCallback(request, operation), scope: me }); request.setConfig({ args: args, directFn: fn }); fn.apply(window, args); return request; }, abort: function(operation) { var id; if (operation && operation.isDataRequest) { operation = operation.getOperation(); } if (operation && operation.isOperation) { id = operation.id; } if (id != null) { this.canceledOperations[id] = true; } }, applyEncoding: Ext.identityFn, createRequestCallback: function(request, operation) { var me = this; return function(data, event) { if (!me.canceledOperations[operation.id]) { me.processResponse(event.status, operation, request, event); } delete me.canceledOperations[operation.id]; }; }, 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', 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.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] = me.bindResponse(request); me.loadScript(request); return request; }, bindResponse: function(request) { var me = this; return function(result) { Ext.elevate(function() { me.handleResponse(result, 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; Ext.undefer(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 ]); }, 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' ], 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', 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', 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', 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', { 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: 'glyph', 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, phantom = me.phantom, result; commit = { silent: true, commit: commit }; if (info.depth != null && info.depth !== me.data.depth) { var childInfo = { depth: info.depth + 1 }, children = me.childNodes, childCount = children.length, i; for (i = 0; i < childCount; i++) { children[i].updateInfo(commit, childInfo); } } result = me.set(info, commit); me.phantom = phantom; return result; }, 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(), halfCheckedValue = treeStore && treeStore.triStateCheckbox ? 1 : false, bulkUpdate = treeStore && treeStore.bulkUpdate, meChecked, nodeChecked, modifiedFields; 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.fireBubbledEvent('beforeappend', [ me, node ]) === false) { Ext.resumeLayouts(true); return false; } index = me.childNodes.length; oldParent = node.parentNode; if (oldParent) { if (suppressEvents !== true && node.fireBubbledEvent('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; modifiedFields = 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].cascade(me.triggerUIUpdate); } if (treeStore) { treeStore.registerNode(me, !bulkUpdate); if (bulkUpdate) { treeStore.registerNode(node); } } if (suppressEvents !== true) { me.fireBubbledEvent('append', [ me, node, index ]); if (oldParent) { node.fireBubbledEvent('move', [ node, oldParent, me, index ]); } } me.callTreeStore('onNodeAppend', [ node, index ]); if (modifiedFields) { node.callJoined('afterEdit', [ modifiedFields ]); } result = node; if (treeStore) { treeStore.endUpdate(); } } Ext.resumeLayouts(true); return result; }, getOwnerTree: function() { var store = this.getTreeStore(); return store && 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, removeRange = []; if (index === -1 || (suppressEvents !== true && me.fireBubbledEvent('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.cascade(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, removeRange ]); node.previousSibling = node.nextSibling = node.parentNode = null; me.fireBubbledEvent('remove', [ me, node, !!isMove, removeContext ]); me.callTreeStore('onNodeRemove', [ [ node ], !!isMove, removeRange ]); } 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, session, deep) { var me = this, result, args = [ newId ], len = me.childNodes ? me.childNodes.length : 0, i; if (session && session.isSession) { args.push(session); } else if (arguments.length < 3) { deep = session; } result = me.callParent(args); if (deep) { for (i = 0; i < len; i++) { result.appendChild(me.childNodes[i].copy(undefined, true)); } } return result; }, clear: function(erase, resetChildren) { var me = this, data; me.parentNode = me.previousSibling = me.nextSibling = null; if (erase) { me.firstChild = me.lastChild = me.childNodes = null; } if (resetChildren) { me.firstChild = me.lastChild = null; me.childNodes.length = 0; if (me.data) { me.data.children = null; } } }, drop: function() { var me = this, childNodes = me.childNodes, parentNode = me.parentNode, len, i, node, treeStore = me.getTreeStore(); me.callParent(); if (parentNode) { parentNode.removeChild(me); } else if (me.get('root')) { treeStore.setRoot(null); } treeStore && treeStore.beginUpdate(); for (i = 0 , len = childNodes ? childNodes.length : 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, modifiedFields, sibling, siblingModifiedFields; if (!refNode) { return me.appendChild(node); } if (node === refNode) { return false; } node = me.createNode(node); if (suppressEvents !== true && me.fireBubbledEvent('beforeinsert', [ me, node, refNode ]) === false) { return false; } if (oldParent === me && me.indexOf(node) < index) { refIndex--; } if (oldParent) { if (suppressEvents !== true && node.fireBubbledEvent('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; } modifiedFields = 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++) { sibling = me.childNodes[i]; siblingModifiedFields = sibling.updateInfo(false, { index: i }); if (siblingModifiedFields) { sibling.callJoined('afterEdit', [ siblingModifiedFields ]); } } 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.fireBubbledEvent('insert', [ me, node, refNode ]); if (oldParent) { node.fireBubbledEvent('move', [ node, oldParent, me, refIndex, refNode ]); } } me.callTreeStore('onNodeInsert', [ node, refIndex ]); if (modifiedFields) { node.callJoined('afterEdit', [ modifiedFields ]); } 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, removeRange = []; if (!len) { return me; } if (!fromParent) { treeStore = me.getTreeStore(); if (treeStore) { treeStore.beginUpdate(); treeStore.suspendEvent('remove'); me.callTreeStore('beforeNodeRemove', [ childNodes, false, removeRange ]); } } for (i = 0; i < len; ++i) { node = childNodes[i]; node.previousSibling = node.nextSibling = node.parentNode = null; me.fireBubbledEvent('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, removeRange ]); 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(spec, scope, args, after) { var me = this, before = spec; if (arguments.length === 1 && !Ext.isFunction(spec)) { after = spec.after; scope = spec.scope; args = spec.args; before = spec.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].cascade.call(childNodes[i], before, scope, args, after); } if (after) { after.apply(scope || me, args || [ me ]); } } }, cascadeBy: function() { return this.cascade.apply(this, arguments); }, 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.fireBubbledEvent('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.cascade(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.fireBubbledEvent('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', 'datachanged'); resumeAddEvent = true; } } } me.callTreeStore('onBeforeNodeExpand', [ me.onChildNodesAvailable, me, [ recursive, callback, scope ] ]); if (resumeAddEvent) { treeStore.resumeEvent('add', 'datachanged'); treeStore.fireEvent('datachanged', treeStore); 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 || !treeStore.isVisible(me)) { me.data.expanded = true; } else { me.set('expanded', true); } if (collapsedAncestors) { for (i = 1; i < collapsedAncestors.length; i++) { ancestor = collapsedAncestors[i]; if (bulkUpdate || !treeStore.isVisible(ancestor)) { ancestor.data.expanded = true; } else { ancestor.set('expanded', true); } } collapsedAncestors[0].expand(); for (i = 1; i < collapsedAncestors.length; i++) { ancestor = collapsedAncestors[i]; ancestor.fireBubbledEvent('expand', [ ancestor, ancestor.childNodes ]); } } else { me.callTreeStore('onNodeExpand', [ records, false ]); } me.fireBubbledEvent('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.fireBubbledEvent('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 || !treeStore.contains(me)) { me.data.expanded = false; } else { me.set('expanded', false); } me.callTreeStore('onNodeCollapse', [ me.childNodes, callback, scope ]); me.fireBubbledEvent('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.fireBubbledEvent('beforecollapse', [ me ]) !== false) { me.data.expanded = false; me.fireBubbledEvent('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.fireBubbledEvent(eventName, Ext.Array.slice(arguments, 1)); }, fireBubbledEvent: function(eventName, args) { var result, eventSource, topNode; if (bubbledEvents[eventName]) { for (eventSource = this; result !== false && eventSource; eventSource = (topNode = eventSource).parentNode) { result = eventSource.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 this.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); } }, addCls: function(cls) { this.replaceCls(null, cls); }, removeCls: function(cls) { this.replaceCls(cls); }, replaceCls: function(oldCls, newCls) { var pieces = this._parseCls(this.data.cls), parts = this._parseCls(oldCls); if (parts.length) { pieces = Ext.Array.difference(pieces, parts); } parts = this._parseCls(newCls); if (parts.length) { pieces = Ext.Array.unique(pieces.concat(parts)); } this.set('cls', pieces.join(' ')); }, toggleCls: function(cls, state) { if (state === undefined) { var pieces = this._parseCls(this.data.cls), parts = this._parseCls(cls), len = parts.length, i, p; for (i = 0; i < len; ++i) { p = parts[i]; if (Ext.Array.contains(pieces, p)) { Ext.Array.remove(pieces, p); } else { pieces.push(p); } } this.set('cls', pieces.join(' ')); } else if (state) { this.addCls(cls); } else { this.removeCls(cls); } }, privates: { _noCls: [], spacesRe: /\s+/, 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); }, _parseCls: function(cls) { if (!cls) { return this._noCls; } if (typeof cls === 'string') { return cls.split(this.spacesRe); } return cls; } } }; } } }); Ext.define('Ext.data.TreeModel', { extend: Ext.data.Model, mixins: [ Ext.mixin.Queryable ], getRefItems: function() { return this.childNodes; }, getRefOwner: function() { return this.parentNode; }, statics: { defaultProxy: 'memory' } }, function() { Ext.data.NodeInterface.decorate(this); }); Ext.define('Ext.data.NodeStore', { extend: Ext.data.Store, alias: 'store.node', isNodeStore: true, config: { node: null, recursive: false, rootVisible: false, folderSort: false }, implicitModel: 'Ext.data.TreeModel', getTotalCount: function() { return this.getCount(); }, updateFolderSort: function(folderSort) { var data = this.getData(); data.setTrackGroups(false); if (folderSort) { data.setGrouper({ groupFn: this.folderSortFn }); } else { data.setGrouper(null); } }, folderSortFn: function(node) { return node.data.leaf ? 1 : 0; }, 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) { if (parent === this.getNode()) { this.add([ node ].concat(this.retrieveChildNodes(node))); } }, onNodeInsert: function(parent, node, refNode) { var me = this, idx; if (parent === me.getNode()) { idx = me.indexOf(refNode) || 0; me.insert(0, [ node ].concat(me.retrieveChildNodes(node))); } }, onNodeRemove: function(parent, node) { if (parent === this.getNode()) { this.remove([ node ].concat(this.retrieveChildNodes(node))); } }, onNodeExpand: function(parent, records) { if (parent === this.getNode()) { this.loadRecords(records); } }, applyNode: function(node) { if (node) { if (!node.isModel) { node = new (this.getModel())(node); } if (!node.isNode) { Ext.data.NodeInterface.decorate(node); } } return node; }, updateNode: function(node, oldNode) { var me = this, data; if (oldNode && !oldNode.destroyed) { oldNode.un({ append: 'onNodeAppend', insert: 'onNodeInsert', remove: 'onNodeRemove', scope: me }); oldNode.unjoin(me); } if (node) { node.on({ scope: me, append: 'onNodeAppend', insert: 'onNodeInsert', remove: 'onNodeRemove' }); 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(); if (me.isInitializing) { me.inlineData = data; } else { me.add(data); } me.resumeEvents(); if (data.length === 0) { me.loaded = node.loaded = true; } me.fireEvent('refresh', me, me.data); } }, 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; }, privates: { 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; } } }); Ext.define('Ext.data.Request', { isDataRequest: true, 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, responseType: 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.data.TreeStore', { extend: Ext.data.Store, alias: 'store.tree', isTreeStore: true, config: { root: null, rootVisible: false, defaultRootProperty: 'children', parentIdProperty: null, clearOnLoad: true, clearRemovedOnLoad: true, nodeParam: 'node', defaultRootId: 'root', defaultRootText: 'Root', folderSort: false, pageSize: null }, filterer: 'topdown', lazyFill: false, fillCount: 0, bulkUpdate: 0, nodesToUnregister: 0, _silentOptions: { silent: true }, implicitModel: 'Ext.data.TreeModel', groupField: null, groupDir: null, grouper: null, 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, oldFields) { 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.callParent([ fields, oldFields ]); }, applyGroupField: function(field) { return null; }, applyGroupDir: function(dir) { return null; }, applyGrouper: function(grouper) { if (grouper) { Ext.raise('You can\'t group a TreeStore'); } return null; }, group: Ext.emptyFn, onSorterEndUpdate: function() { var me = this, sorterCollection = me.getSorters(), sorters = sorterCollection.getRange(), rootNode = me.getRoot(), folderSort = me.getFolderSort(); me.fireEvent('beforesort', me, sorters); if (rootNode && (folderSort || sorters.length)) { if (me.getRemoteSort()) { if (sorters.length) { me.load({ 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); }; }, getTotalCount: function() { return this.getCount(); }, afterEdit: function(node, modifiedFieldNames) { var me = this, parentNode = node.parentNode, rootVisible = me.getRootVisible(), isHiddenRoot = !parentNode && !rootVisible, prevVisibleNodeIndex, isVisible = node.get('visible'), toAdd, removeStart; if (!isHiddenRoot && isVisible !== me.contains(node)) { if (isVisible) { if (!parentNode || me.isVisible(node)) { toAdd = [ node ]; if (node.isExpanded()) { me.handleNodeExpand(node, node.childNodes, toAdd); } prevVisibleNodeIndex = node.previousSibling ? me.indexOfPreviousVisibleNode(node.previousSibling) : (parentNode ? me.indexOf(parentNode) : -1); me.insert(prevVisibleNodeIndex + 1, toAdd); } } else { removeStart = me.indexOf(node); me.removeAt(removeStart, me.indexOfNextVisibleNode(node) - removeStart); } } else if (me.getRoot() && me.needsLocalFilter()) { me.onFilterEndUpdate(me.getFilters()); } me.callParent([ node, modifiedFieldNames ]); }, 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); } }, 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; }, 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; }, updateModel: function(model) { if (model) { var isNode = model.prototype.isNode; Ext.data.NodeInterface.decorate(model); if (!isNode && !this.changingProxy) { this.getProxy().getReader().buildExtractors(true); } } }, onCollectionFilter: Ext.emptyFn, 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.cascade({ 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.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() && root.get('visible')) { toAdd.push(root); } 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())) { 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 { 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); } }); me.flushLoad(); } } }, 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.loadCount; 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, { silent: true }); record.expand(); } } } } } }, onNodeCollapse: function(parent, records, callback, scope) { var me = this, collapseIndex = me.indexOf(parent) + 1, lastNodeIndexPlus; if (me.needsLocalFilter()) { records = Ext.Array.filter(records, me.filterVisible); } if (records.length && me.isVisible(parent)) { 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(); }, indexOfPreviousVisibleNode: function(node) { var result; for (result = node; result && !result.get('visible'); result = result.previousSibling) {} if (result) { if (result.isExpanded() && result.lastChild) { return this.indexOfPreviousVisibleNode(result.lastChild); } } else { result = node.parentNode; } return this.indexOf(result); }, 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); }, getRejectRecords: function() { return Ext.Array.filter(Ext.Object.getValues(this.byIdMap), this.filterRejects, this); }, getUpdatedRecords: function() { return Ext.Array.filter(Ext.Object.getValues(this.byIdMap), this.filterUpdated); }, beforeNodeRemove: function(parentNode, childNodes, isMove, removeRange) { if (!Ext.isArray(childNodes)) { childNodes = [ childNodes ]; } var me = this, len = childNodes.length, removed = me.removedNodes, i, startNode; for (i = 0; !startNode && i < len; i++) { if (childNodes[i].get('visible')) { startNode = childNodes[i]; } } if (startNode) { removeRange[0] = me.indexOf(childNodes[0]); removeRange[1] = me.indexOfNextVisibleNode(childNodes[childNodes.length - 1]) - removeRange[0]; } else { removeRange[0] = -1; removeRange[1] = 0; } for (i = 0; i < len; i++) { childNodes[i].cascade(function(node) { me.unregisterNode(node, true); if (removed && !isMove) { if (!node.phantom && !node.erasing && !me.loading) { node.removedFrom = me.indexOf(node); removed.push(node); me.needsSync = true; } } }); } }, afterDrop: Ext.emptyFn, onNodeRemove: function(parentNode, childNodes, isMove, removeRange) { var me = this; me.suspendAutoSync(); if (removeRange[0] !== -1) { me.removeIsMove = isMove; me.removeAt.apply(me, removeRange); me.removeIsMove = false; } 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, removed = me.removedNodes, storeReader, nodeProxy, nodeReader, reader, dataRoot, storeInsertionPoint; if (parent && me.needsLocalFilter()) { me.doFilter(parent); } me.beginUpdate(); if (me.isVisible(node)) { if (index === 0 || !node.previousSibling) { storeInsertionPoint = me.indexOf(parent); } else { storeInsertionPoint = me.indexOfPreviousVisibleNode(node.previousSibling); } me.insert(storeInsertionPoint + 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(); } } } Ext.Array.remove(removed, node); 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, was = me.byIdMap[node.id], children, length, i; me.byIdMap[node.id] = node; if (node.onRegisterTreeNode && node !== was) { node.onRegisterTreeNode(me); } if (node.onUnregisterTreeNode) { me.nodesToUnregister++; } 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, was = me.byIdMap[node.id], 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); } } if (node.onUnregisterTreeNode && node === was) { node.onUnregisterTreeNode(me); me.nodesToUnregister--; } }, onNodeSort: function(node, childNodes) { var me = this; me.suspendAutoSync(); if ((me.indexOf(node) !== -1 && node.isExpanded()) || (node === me.getRoot() && !me.getRootVisible())) { 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); } return newRoot; }, updateRoot: function(newRoot, oldRoot) { var me = this, oldOwner, initial = !oldRoot, toRemove, removeRange = []; me.getTrackRemoved(); me.suspendEvent('add', 'remove'); if (initial) { me.suspendEvent('refresh', 'datachanged'); } if (oldRoot && oldRoot.isModel) { if (me.getRootVisible()) { toRemove = [ oldRoot ]; } else { toRemove = oldRoot.childNodes; } me.beforeNodeRemove(null, toRemove, false, removeRange); oldRoot.set('root', false); me.onNodeRemove(null, toRemove, false, removeRange); oldRoot.fireEvent('remove', null, oldRoot, false); oldRoot.fireEvent('rootchange', null); oldRoot.clearListeners(); oldRoot.store = oldRoot.treeStore = null; me.unregisterNode(oldRoot); } 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.store = newRoot.treeStore = me; 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; } } if (!initial) { me.fireEvent('rootchange', newRoot, oldRoot); } if (newRoot && (me.getAutoLoad() || newRoot.isExpanded())) { if (newRoot.isLoaded()) { me.onNodeExpand(newRoot, newRoot.childNodes); if (!initial) { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); } } else { newRoot.data.expanded = false; newRoot.expand(false); if (newRoot.isLoaded && !me.getProxy().isSynchronous && !initial) { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); } } } else if (!initial) { me.fireEvent('datachanged', me); me.fireEvent('refresh', me); } me.resumeEvent('add', 'remove'); if (initial) { me.resumeEvent('refresh', 'datachanged'); } }, doDestroy: function() { var me = this, root = me.getRoot(); if (root && me.nodesToUnregister) { root.cascade(function(node) { if (node.onUnregisterTreeNode) { node.onUnregisterTreeNode(me); } }); } me.callParent(); }, each: function(fn, scope, includeOptions) { var i = 0, filtered = includeOptions, includeCollapsed; if (includeOptions && typeof includeOptions === 'object') { includeCollapsed = includeOptions.collapsed; filtered = includeOptions.filtered; } if (includeCollapsed) { this.getRoot().cascade(function(node) { if (filtered === true || node.get('visible')) { return fn.call(scope || node, node, i++); } }); } else { return this.callParent([ fn, scope, filtered ]); } }, collect: function(dataIndex, options, filtered) { var includeCollapsed, map = {}, result = [], allowNull = options, strValue, value; if (options && typeof options === 'object') { includeCollapsed = options.collapsed; filtered = options.filtered; allowNull = options.allowNull; } if (includeCollapsed || filtered) { this.getRoot().cascade(function(node) { if (filtered === true || node.get('visible')) { value = node.get(dataIndex); strValue = String(value); if ((allowNull || !Ext.isEmpty(value)) && !map[strValue]) { map[strValue] = 1; result.push(value); } } if (!includeCollapsed && !node.isExpanded()) { return false; } }); } else { result = this.callParent([ dataIndex, allowNull, filtered ]); } return result; }, getNodeById: function(id) { return this.byIdMap[id] || null; }, findNode: function(fieldName, value, startsWith, endsWith, ignoreCase) { if (Ext.isEmpty(value, false)) { return null; } if (fieldName === 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(fieldName))) { result = node; return false; } }); return result; }, load: function(options) { var node = options && options.node; if (!node && !(node = this.getRoot())) { node = this.setRoot({ expanded: true, autoRoot: true }); return; } if (node.isLoading()) { return; } return this.callParent([ options ]); }, reload: function(options) { var o = Ext.apply({}, options, this.lastOptions); o.node = this.getRoot(); return this.load(o); }, flushLoad: function() { var me = this, options = me.pendingLoadOptions, node, callback, scope, clearOnLoad = me.getClearOnLoad(), isRootLoad, operation, doClear; me.clearLoadTask(); if (!options) { return; } node = options.node || me.getRoot(); isRootLoad = node && node.isRoot(); callback = options.callback; scope = options.scope; options.params = options.params || {}; if (node.data.expanded && !isRootLoad) { 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(); me.setLoadOptions(options); if (me.getRemoteSort() && options.sorters) { me.fireEvent('beforesort', me, options.sorters); } options = Ext.apply({ node: options.node || node, internalScope: me, internalCallback: me.onProxyLoad }, options); me.lastOptions = Ext.apply({}, options); options.isRootLoad = isRootLoad; operation = me.createOperation('read', options); if (me.fireEvent('beforeload', me, operation) !== false) { me.loading = true; if (isRootLoad) { if (me.getClearRemovedOnLoad()) { me.removedNodes.length = 0; } if (clearOnLoad) { me.unregisterNode(node, true); node.clear(false, true); me.registerNode(node); doClear = true; } } else { if (me.loading) { node.data.loaded = false; } if (me.getTrackRemoved() && me.getClearRemovedOnLoad()) { me.clearRemoved(node); } if (clearOnLoad) { node.removeAll(false); } } if (me.loading && node) { node.set('loading', true, { silent: !(me.contains(node) || node === me.getRoot()) }); } 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, isRootLoad = options.isRootLoad, scope = operation.getScope() || me, args = [ records, operation, successful ]; if (me.destroyed) { 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 (isRootLoad) { me.suspendEvent('add', 'update'); } records = me.fillNode(node, records); } Ext.callback(options.onChildNodesAvailable, scope, args); if (isRootLoad) { me.resumeEvent('add', 'update'); me.callObservers('BeforePopulate'); me.fireEvent('datachanged', me); me.fireEvent('refresh', me); me.callObservers('AfterPopulate'); } 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; if (++me.bulkUpdate === 1) { me.suspendEvent('datachanged'); } if (newNodeCount) { me.setupNodes(newNodes); node.appendChild(newNodes, undefined, true); } else { if (me.bulkUpdate === 1) { node.set('loaded', true); } else { node.data.loaded = true; } } if (!--me.bulkUpdate) { me.resumeEvent('datachanged'); } return newNodes; }, setupNodes: function(newNodes) { var me = this, sorters = me.getSorters(), needsIndexSort = false, newNodeCount = newNodes.length, performLocalSort = me.sortOnLoad && newNodeCount > 1 && !me.getRemoteSort() && me.getFolderSort() || sorters.length, performLocalFilter = me.needsLocalFilter(), node1, node2, i; if (performLocalFilter) { me.doFilter(newNodes[0]); } for (i = 1; i < newNodeCount; i++) { node1 = newNodes[i]; node2 = newNodes[i - 1]; if (performLocalFilter) { me.doFilter(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); } }, 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, parent, id, children; for (i = 0; i < len; i++) { node = records[i]; node.data.depth = 1; 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 + '"'); } parent = nodeMap[parentId]; parent.$children = parent.$children || []; parent.$children.push(node); node.data.depth = parent.data.depth + 1; } } for (id in nodeMap) { node = nodeMap[id]; children = node.$children; if (children) { delete node.$children; me.setupNodes(children); node.appendChild(children); } me.registerNode(node); } me.setupNodes(result); 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: { fireChangeEvent: function(record) { return !!this.byIdMap[record.id]; }, getRawRemovedRecords: function() { return this.removedNodes; }, createOperation: function(type, options) { var me = this, node = options.node, proxy; if (me.useModelProxy && node && node !== me.getRootNode()) { proxy = node.getProxy(); } if (proxy && proxy !== me.getProxy()) { return proxy.createOperation(type, options); } else { return me.callParent([ type, options ]); } }, recordCreator: function(data, Model) { return new Model(data); }, doFilter: function(node) { this.filterNodes(node, this.getFilters().getFilterFn(), true); }, filterNodes: function(node, filterFn, parentVisible) { var me = this, bottomUpFiltering = me.filterer === 'bottomup', match = filterFn(node) && parentVisible || (node.isRoot() && !me.getRootVisible()), childNodes = node.childNodes, len = childNodes && childNodes.length, i, matchingChildren; if (len) { for (i = 0; i < len; ++i) { matchingChildren = me.filterNodes(childNodes[i], filterFn, match || bottomUpFiltering) || matchingChildren; } if (bottomUpFiltering) { match = matchingChildren || match; } } node.set("visible", match, me._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 }, 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; this.isBase = record.self === Ext.data.Model; 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) { if (this.isBase) { return; } 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, null, record); 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 (val && val.join) { val = val.join(' '); } 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) { 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.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.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' ], _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.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.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, defaultValue); }, getNodeValue: function(node, defaultValue) { if (typeof node.normalize == 'function') { node.normalize(); } var firstChild = node && node.firstChild, v = firstChild ? firstChild.nodeValue : null; if (defaultValue !== undefined && (v == null || v === '')) { v = defaultValue; } return 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, alternateClassName: 'Ext.data.XmlReader', alias: 'reader.xml', config: { record: '', namespace: '' }, responseType: 'document', createAccessor: function(expr) { if (Ext.isEmpty(expr)) { return Ext.emptyFn; } if (Ext.isFunction(expr)) { return expr; } return function(root) { return this.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) { return this.getRootValue(data, this.getRootProperty()); }, extractData: function(root, readOptions) { var recordName = this.getRecord(); if (!recordName) { Ext.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 namespace = this.getNamespace(), selector, autoMapping, result; if (field.mapping) { selector = field.mapping; } else { selector = (namespace ? namespace + '|' : '') + field.name; autoMapping = true; } if (typeof selector === 'function') { result = function(raw, self) { return field.mapping(raw, self); }; } else { if (autoMapping && !namespace && Ext.supports.XmlQuerySelector) { result = function(raw, self) { return self.getNodeValue(raw.querySelector(selector)); }; } if (!result) { result = function(raw, self) { return self.getNodeValue(Ext.DomQuery.selectNode(selector, raw)); }; } } return result; }, privates: { getGroupRoot: function(data) { return this.getRootValue(data, this.getGroupRootProperty()); }, getRootValue: function(data, prop) { var nodeName = data.nodeName; if (!prop || (nodeName && nodeName == prop)) { return data; } else if (typeof prop === 'function') { return prop(data); } else if (Ext.DomQuery.isXml(data)) { return Ext.DomQuery.selectNode(prop, data); } }, getSummaryRoot: function(data) { return this.getRootValue(data, this.getSummaryRootProperty()); } }, 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', 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', config: { id: undefined }, constructor: function(config) { this.callParent(arguments); this.cache = {}; if (this.getStorageObject() === undefined) { Ext.raise("Local Storage is not supported in this browser, please use another type of data proxy"); } if (this.getId() === undefined) { Ext.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) { 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, value; for (; i < length; i++) { field = fields[i]; name = field.name; if (field.persist) { value = rawData[name]; if (field.isDateField && field.dateFormat && Ext.isDate(value)) { value = Ext.Date.format(value, field.dateFormat); } else if (field.serialize) { value = field.serialize(value, record); } data[name] = value; } } 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.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.summary.Base', { mixins: [ Ext.mixin.Factoryable ], alias: 'data.summary.base', isAggregator: true, factoryConfig: { defaultType: 'base', cacheable: true }, constructor: function(config) { var calculate = config && config.calculate; if (calculate) { config = Ext.apply({}, config); delete config.calculate; this.calculate = calculate; } this.initConfig(config); }, extractValue: function(record, property, root) { var ret; if (record) { if (root) { record = record[root]; } ret = record[property]; } return ret; } }, function() { Ext.Factory.on('dataSummary', function(factory, config) { if (typeof config === 'function') { return factory({ calculate: config }); } }); }); Ext.define('Ext.data.summary.Sum', { extend: Ext.data.summary.Base, alias: 'data.summary.sum', calculate: function(records, property, root, begin, end) { var n = end - begin, i, sum, v; for (i = 0; i < n; ++i) { v = this.extractValue(records[begin + i], property, root); sum = i ? sum + v : v; } return sum; } }); Ext.define('Ext.data.summary.Average', { extend: Ext.data.summary.Sum, alias: 'data.summary.average', calculate: function(records, property, root, begin, end) { var len = end - begin, value; if (len > 0) { value = this.callParent([ records, property, root, begin, end ]) / len; } return value; } }); Ext.define('Ext.data.summary.Count', { extend: Ext.data.summary.Base, alias: 'data.summary.count', calculate: function(records, property, root, begin, end) { return end - begin; } }); Ext.define('Ext.data.summary.Max', { extend: Ext.data.summary.Base, alias: 'data.summary.max', calculate: function(records, property, root, begin, end) { var max = this.extractValue(records[begin], property, root), i, v; for (i = begin; i < end; ++i) { v = this.extractValue(records[i], property, root); if (v > max) { max = v; } } return max; } }); Ext.define('Ext.data.summary.Min', { extend: Ext.data.summary.Base, alias: 'data.summary.min', calculate: function(records, property, root, begin, end) { var min = this.extractValue(records[begin], property, root), i, v; for (i = begin; i < end; ++i) { v = this.extractValue(records[i], property, root); if (v < min) { min = v; } } return min; } }); Ext.define('Ext.data.validator.AbstractDate', { extend: Ext.data.validator.Validator, config: { message: null, format: '' }, applyFormat: function(format) { if (!format) { format = this.getDefaultFormat(); } if (!Ext.isArray(format)) { format = [ format ]; } return format; }, parse: function(value) { if (Ext.isDate(value)) { return value; } var me = this, format = me.getFormat(), len = format.length, ret = null, i; for (i = 0; i < len && !ret; ++i) { ret = Ext.Date.parse(value, format[i], true); } return ret; }, validate: function(value) { return this.parse(value) ? true : this.getMessage(); } }); 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: 'Value must be greater than {0}', maxOnlyMessage: 'Value must be less than {0}', bothMessage: 'Value must be between {0} and {1}' }, resetMessages: function() { this._bothMsg = this._minMsg = this._maxMsg = null; }, updateMin: function() { this.resetMessages(); }, updateMax: function() { this.resetMessages(); }, updateMinOnlyMessage: function() { this.resetMessages(); }, updateMaxOnlyMessage: function() { this.resetMessages(); }, updateBothMessage: function() { this.resetMessages(); }, validate: function(value) { var me = this, min = me.getMin(), max = me.getMax(), hasMin = (min != null), hasMax = (max != null), msg = this.validateValue(value); if (msg !== true) { return msg; } value = me.getValue(value); if (hasMin && hasMax) { if (value < min || value > max) { msg = me._bothMsg || (me._bothMsg = Ext.String.format(me.getBothMessage(), min, max)); } } else if (hasMin) { if (value < min) { msg = me._minMsg || (me._minMsg = Ext.String.format(me.getMinOnlyMessage(), min)); } } else if (hasMax) { if (value > max) { msg = me._maxMsg || (me._maxMsg = Ext.String.format(me.getMaxOnlyMessage(), max)); } } 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.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.CIDRv4', { extend: Ext.data.validator.Format, alias: 'data.validator.cidrv4', type: 'cidrv4', message: 'Is not a valid CIDR block', matcher: /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/ }); Ext.define('Ext.data.validator.CIDRv6', { extend: Ext.data.validator.Format, alias: 'data.validator.cidrv6', type: 'cidrv6', message: 'Is not a valid CIDR block', matcher: /^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$/ }); Ext.define('Ext.data.validator.Number', { extend: Ext.data.validator.Validator, alias: 'data.validator.number', type: 'number', config: { decimalSeparator: undefined, message: 'Is not a valid number', thousandSeparator: undefined }, constructor: function(config) { this.callParent([ config ]); this.rebuildMatcher(); }, applyDecimalSeparator: function(v) { return v === undefined ? Ext.util.Format.decimalSeparator : v; }, updateDecimalSeparator: function() { this.rebuildMatcher(); }, applyThousandSeparator: function(v) { return v === undefined ? Ext.util.Format.thousandSeparator : v; }, updateThousandSeparator: function() { this.rebuildMatcher(); }, parse: function(v) { var sep = this.getDecimalSeparator(), N = Ext.Number; if (typeof v === 'string') { if (!this.matcher.test(v)) { return null; } v = this.parseValue(v); } return sep ? N.parseFloat(v) : N.parseInt(v); }, validate: function(value) { return this.parse(value) === null ? this.getMessage() : true; }, privates: { getMatcherText: function(preventSign) { var t = this.getThousandSeparator(), d = this.getDecimalSeparator(), s = '(?:'; if (t) { t = Ext.String.escapeRegex(t); s += '(?:\\d{1,3}(' + t + '\\d{3})*)|'; } s += '\\d*)'; if (d) { d = Ext.String.escapeRegex(d); s += '(?:' + d + '\\d*)?'; } if (!preventSign) { s = this.getSignPart() + s; } return s; }, getSignPart: function() { return '(\\+|\\-)?'; }, parseValue: function(v) { var thousandMatcher = this.thousandMatcher, decimal; if (thousandMatcher) { v = v.replace(thousandMatcher, ''); } decimal = this.getDecimalSeparator(); if (decimal && decimal !== '.') { v = v.replace(decimal, '.'); } return v; }, rebuildMatcher: function() { var me = this, sep; if (!me.isConfiguring) { sep = me.getThousandSeparator(); me.matcher = new RegExp('^' + me.getMatcherText() + '$'); if (sep) { me.thousandMatcher = sep ? new RegExp(Ext.String.escapeRegex(sep), 'g') : null; } } } } }); Ext.define('Ext.data.validator.Currency', { extend: Ext.data.validator.Number, alias: 'data.validator.currency', type: 'currency', config: { symbolAtEnd: undefined, spacer: undefined, symbol: undefined }, message: 'Is not a valid currency amount', applySymbolAtEnd: function(value) { return value === undefined ? Ext.util.Format.currencyAtEnd : value; }, updateSymbolAtEnd: function() { this.rebuildMatcher(); }, applySpacer: function(value) { return value === undefined ? Ext.util.Format.currencySpacer : value; }, updateSpacer: function() { this.rebuildMatcher(); }, applySymbol: function(value) { return value === undefined ? Ext.util.Format.currencySign : value; }, updateSymbol: function() { this.rebuildMatcher(); }, privates: { getMatcherText: function() { var me = this, ret = me.callParent([ true ]), symbolPart = me.getSymbolMatcher(); if (me.getSymbolAtEnd()) { ret += symbolPart; } else { ret = symbolPart + ret; } return me.getSignPart() + ret; }, getSymbolMatcher: function() { var symbol = Ext.String.escapeRegex(this.getSymbol()), spacer = Ext.String.escapeRegex(this.getSpacer() || ''), s = this.getSymbolAtEnd() ? (spacer + symbol) : (symbol + spacer); return '(?:' + s + ')?'; }, parseValue: function(v) { v = v.replace(this.currencyMatcher, this.atEnd ? '' : '$1'); return this.callParent([ v ]); }, rebuildMatcher: function() { var me = this, symbolPart, atEnd, sign; me.callParent(); if (!me.isConfiguring) { atEnd = me.getSymbolAtEnd(); symbolPart = me.getSymbolMatcher(); sign = me.getSignPart(); me.atEnd = atEnd; me.currencyMatcher = new RegExp(atEnd ? (symbolPart + '$') : ('^' + sign + symbolPart)); } } } }); Ext.define('Ext.data.validator.CurrencyUS', { extend: Ext.data.validator.Currency, alias: 'data.validator.currency-us', type: 'currency-us', thousandSeparator: ',', decimalSeparator: '.', symbol: '$', spacer: '', symbolAtEnd: false }); Ext.define('Ext.data.validator.Date', { extend: Ext.data.validator.AbstractDate, alias: 'data.validator.date', type: 'date', isDateValidator: true, message: 'Is not a valid date', privates: { getDefaultFormat: function() { return [ Ext.Date.defaultFormat, 'm/d/Y', 'n/j/Y', 'n/j/y', 'm/j/y', 'n/d/y', 'm/j/Y', 'n/d/Y', 'm-d-y', 'n-d-y', 'm-d-Y', 'mdy', 'mdY', 'Y-m-d' ]; } } }); Ext.define('Ext.data.validator.DateTime', { extend: Ext.data.validator.AbstractDate, alias: 'data.validator.datetime', type: 'datetime', isDateTimeValidator: true, message: 'Is not a valid date and time', privates: { getDefaultFormat: function() { var D = Ext.Date; return D.defaultFormat + ' ' + D.defaultTimeFormat; } } }); Ext.define('Ext.data.validator.Email', { extend: Ext.data.validator.Format, alias: 'data.validator.email', type: 'email', 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, message: 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', message: 'Is a value that has been excluded', constructor: function() { this.callParent(arguments); if (!this.getList()) { Ext.raise('validator.Exclusion requires a list'); } }, inclusion: false }); Ext.define('Ext.data.validator.IPAddress', { extend: Ext.data.validator.Format, alias: 'data.validator.ipaddress', type: 'ipaddress', message: 'Is not a valid IP address', matcher: new RegExp('^(' + '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' + '|' + '((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))' + ')$') }); Ext.define('Ext.data.validator.Inclusion', { extend: Ext.data.validator.List, alias: 'data.validator.inclusion', type: 'inclusion', message: 'Is not in the list of acceptable values', constructor: function() { this.callParent(arguments); if (!this.getList()) { Ext.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', 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', isPresence: true, 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.NotNull', { extend: Ext.data.validator.Presence, alias: 'data.validator.notnull', type: 'notnull', allowEmpty: true }); Ext.define('Ext.data.validator.Phone', { extend: Ext.data.validator.Format, alias: 'data.validator.phone', type: 'phone', message: 'Is not a valid phone number', matcher: new RegExp('^ *' + '(?:' + '\\+?' + '(\\d{1,3})' + '[- .]?' + ')?' + '(?:' + '(?:' + '(\\d{3})' + '|' + '\\((\\d{3})\\)' + ')?' + '[- .]?' + ')' + '(?:' + '([2-9]\\d{2})' + '[- .]?' + ')' + '(\\d{4})' + '(?: *(?:e?xt?) *(\\d*))?' + ' *$') }); Ext.define('Ext.data.validator.Range', { extend: Ext.data.validator.Bound, alias: 'data.validator.range', type: 'range', minOnlyMessage: 'Must be at least {0}', maxOnlyMessage: 'Must be no more than than {0}', bothMessage: 'Must be between {0} and {1}', config: { 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.data.validator.Time', { extend: Ext.data.validator.AbstractDate, alias: 'data.validator.time', type: 'time', isTimeValidator: true, message: 'Is not a valid time', privates: { getDefaultFormat: function() { return Ext.Date.defaultTimeFormat; } } }); Ext.define('Ext.data.validator.Url', { extend: Ext.data.validator.Format, alias: 'data.validator.url', type: 'url', message: 'Is not a valid URL', matcher: /^(http:\/\/|https:\/\/|ftp:\/\/|\/\/)([-a-zA-Z0-9@:%_\+.~#?&//=])+$/ }); Ext.define('Ext.data.virtual.Group', { isVirtualGroup: true, firstRecords: null, id: '', summaryRecord: null, constructor: function(key) { this.id = key; this.firstRecords = []; }, first: function() { return this.firstRecords[0] || null; }, getGroupKey: function() { return this.id; }, getSummaryRecord: function() { return this.summaryRecord; } }); Ext.define('Ext.data.virtual.Page', { isVirtualPage: true, begin: 0, end: 0, error: null, locked: null, number: 0, operation: null, pageMap: null, records: null, state: null, constructor: function(config) { var me = this, pageSize; Ext.apply(me, config); pageSize = me.pageMap.store.getPageSize(); me.begin = me.number * pageSize; me.end = me.begin + pageSize; me.locks = { active: 0, prefetch: 0 }; }, destroy: function() { var me = this, operation = me.operation; me.state = 'destroyed'; if (operation) { operation.abort(); } me.callParent(); }, adjustLock: function(kind, delta) { var me = this, locks = me.locks, pageMap = me.pageMap, locked = null, lockedWas = me.locked; if (!(kind in locks)) { Ext.raise('Bad lock type (expected "active" or "prefetch"): "' + kind + '"'); } if (delta !== 1 && delta !== -1) { Ext.raise('Invalid lock count delta (should be 1 or -1): ' + delta); } locks[kind] += delta; if (locks.active) { locked = 'active'; } else if (locks.prefetch) { locked = 'prefetch'; } if (locked !== lockedWas) { me.locked = locked; if (pageMap) { pageMap.onPageLockChange(me, locked, lockedWas); } } }, clearRecords: function(out, by) { var me = this, begin = me.begin, records = me.records, i, n; if (records) { n = records.length; if (by) { for (i = 0; i < n; ++i) { delete out[records[i][by]]; } } else { for (i = 0; i < n; ++i) { delete out[begin + i]; } } } }, fillRecords: function(out, by, withIndex) { var me = this, records = me.records, begin = me.begin, i, n, record; if (records) { n = records.length; if (by) { for (i = 0; i < n; ++i) { record = records[i]; out[record[by]] = withIndex ? begin + i : record; } } else { for (i = 0; i < n; ++i) { out[begin + i] = records[i]; } } } }, isInitial: function() { return this.state === null; }, isLoaded: function() { return this.state === 'loaded'; }, isLoading: function() { return this.state === 'loading'; }, load: function() { var me = this, operation; me.state = 'loading'; operation = me.pageMap.store.loadVirtualPage(me, me.onLoad, me); if (me.state === 'loading') { me.operation = operation; } }, privates: { onLoad: function(operation) { var me = this; me.operation = null; if (!me.destroyed) { if (!(me.error = operation.getError())) { me.records = operation.getRecords(); me.state = 'loaded'; } else { me.state = 'error'; } me.pageMap.onPageLoad(me); } } } }); Ext.define('Ext.data.virtual.PageMap', { isVirtualPageMap: true, config: { cacheSize: 10, concurrentLoading: 1, pageCount: null }, generation: 0, store: null, constructor: function(config) { var me = this; me.prefetchSortFn = me.prefetchSortFn.bind(me); me.initConfig(config); me.clear(); }, destroy: function() { this.clear(true); this.callParent(); }, canSatisfy: function(range) { var end = this.getPageIndex(range.end), pageCount = this.getPageCount(); return pageCount === null || end < pageCount; }, clear: function(destroy) { var me = this, alive = !destroy || null, pages = me.pages, pg; ++me.generation; me.byId = alive && {}; me.byInternalId = alive && {}; me.cache = alive && []; me.indexMap = alive && {}; me.pages = alive && {}; me.loading = alive && []; me.loadQueues = alive && { active: [], prefetch: [] }; if (pages) { for (pg in pages) { me.destroyPage(pages[pg]); } } }, getPage: function(number, autoCreate) { var me = this, pageCount = me.getPageCount(), pages = me.pages, page; if (pageCount === null || number < pageCount) { page = pages[number]; if (!page && autoCreate !== false) { pages[number] = page = new Ext.data.virtual.Page({ pageMap: me, number: number }); } } else { Ext.raise('Invalid page number ' + number + ' when limit is ' + pageCount); } return page || null; }, getPageIndex: function(index) { if (index.isEntity) { index = this.indexOf(index); } return Math.floor(index / this.store.getPageSize()); }, getPageOf: function(index, autoCreate) { var pageSize = this.store.getPageSize(), n = Math.floor(index / pageSize); return this.getPage(n, autoCreate); }, getPages: function(begin, end) { var pageSize = this.store.getPageSize(), first = Math.floor(begin / pageSize), last = Math.ceil(end / pageSize), ret = {}, n; for (n = first; n < last; ++n) { ret[n] = this.getPage(n); } return ret; }, flushNextLoad: function() { var me = this, queueTimer = me.queueTimer; if (queueTimer) { Ext.unasap(queueTimer); } me.loadNext(); }, indexOf: function(record) { var ret = this.indexMap[record.internalId]; return (ret || ret === 0) ? ret : -1; }, getByInternalId: function(internalId) { var index = this.indexMap[internalId], page; if (index || index === 0) { page = this.pages[Math.floor(index / this.store.getPageSize())]; if (page) { return page.records[index - page.begin]; } } }, updatePageCount: function(pageCount, oldPageCount) { var pages = this.pages, pageNumber, page; if (oldPageCount === null || pageCount < oldPageCount) { for (pageNumber in pages) { page = pages[pageNumber]; if (page.number >= pageCount) { this.clearPage(page); this.destroyPage(page); } } } }, privates: { queueTimer: null, clearPage: function(page, fromCache) { var me = this, A = Ext.Array, loadQueues = me.loadQueues; delete me.pages[page.number]; page.clearRecords(me.byId, 'id'); page.clearRecords(me.byInternalId, 'internalId'); page.clearRecords(me.indexMap, 'internalId'); A.remove(loadQueues.active, page); A.remove(loadQueues.prefetch, page); if (!fromCache) { Ext.Array.remove(me.cache, page); } }, destroyPage: function(page) { this.store.onPageDestroy(page); page.destroy(); }, loadNext: function() { var me = this, concurrency = me.getConcurrentLoading(), loading = me.loading, loadQueues = me.loadQueues, page; me.queueTimer = null; while (loading.length < concurrency) { if (!(page = loadQueues.active.shift() || loadQueues.prefetch.shift())) { break; } loading.push(page); page.load(); } }, onPageLoad: function(page) { var me = this, store = me.store, activeRanges = store.activeRanges, n = activeRanges.length, i; Ext.Array.remove(me.loading, page); if (!page.error) { page.fillRecords(me.byId, 'id'); page.fillRecords(me.byInternalId, 'internalId'); page.fillRecords(me.indexMap, 'internalId', true); store.onPageDataAcquired(page); for (i = 0; i < n; ++i) { activeRanges[i].onPageLoad(page); } } me.flushNextLoad(); }, onPageLockChange: function(page, state, oldState) { var me = this, cache = me.cache, loadQueues = me.loadQueues, store = me.store, cacheSize, concurrency; if (page.isInitial()) { if (oldState) { Ext.Array.remove(loadQueues[oldState], page); } if (state) { loadQueues[state].push(page); concurrency = me.getConcurrentLoading(); if (!me.queueTimer && me.loading.length < concurrency) { me.queueTimer = Ext.asap(me.loadNext, me); } } } if (state) { if (!oldState) { Ext.Array.remove(cache, page); } } else { cache.push(page); for (cacheSize = me.getCacheSize(); cache.length > cacheSize; ) { page = cache.shift(); me.clearPage(page, true); store.onPageEvicted(page); me.destroyPage(page); } } }, prefetchSortFn: function(a, b) { a = a.number; b = b.number; var M = Math, firstPage = this.sortFirstPage, lastPage = this.sortLastPage, direction = this.sortDirection, aDir = a < firstPage, bDir = b < firstPage, ret; a = aDir ? M.abs(firstPage - a) : M.abs(lastPage - a); b = bDir ? M.abs(firstPage - b) : M.abs(lastPage - b); if (a === b) { ret = aDir ? direction : -direction; } else { ret = a - b; } return ret; }, prioritizePrefetch: function(direction, firstPage, lastPage) { var me = this; me.sortDirection = direction; me.sortFirstPage = firstPage; me.sortLastPage = lastPage; me.loadQueues.prefetch.sort(me.prefetchSortFn); } } }); Ext.define('Ext.data.virtual.Range', { extend: Ext.data.Range, isVirtualRange: true, callback: null, prefetch: false, scope: null, direction: 1, constructor: function(config) { this.adjustingPages = []; this.callParent([ config ]); }, reset: function() { var me = this; me.records = {}; me.activePages = me.prefetchPages = null; }, privates: { adjustPageLocks: function(kind, adjustment) { var me = this, pages = me.adjustingPages, n = pages.length, i; if (n > 1) { pages.sort(me.direction < 0 ? me.pageSortBackFn : me.pageSortFwdFn); } for (i = 0; i < n; ++i) { pages[i].adjustLock(kind, adjustment); } pages.length = 0; }, doGoto: function() { var me = this, begin = me.begin, end = me.end, prefetch = me.prefetch, records = me.records, store = me.store, pageMap = store.pageMap, limit = store.totalCount, beginWas = me.lastBegin, endWas = me.lastEnd, activePagesWas = me.activePages, prefetchPagesWas = me.prefetchPages, beginBufferZone = me.trailingBufferZone, endBufferZone = me.leadingBufferZone, adjustingPages = me.adjustingPages, activePages, page, pg, direction, prefetchBegin, prefetchEnd, prefetchPages; adjustingPages.length = 0; if ((begin > beginWas && end < endWas) || (begin < beginWas && end > endWas)) { direction = me.direction; } else { direction = (begin < beginWas) ? -1 : ((begin > beginWas) ? 1 : me.direction); } if (direction < 0) { pg = beginBufferZone; beginBufferZone = endBufferZone; endBufferZone = pg; } me.direction = direction; me.activePages = activePages = pageMap.getPages(begin, end); if (prefetch) { me.prefetchBegin = prefetchBegin = Math.max(0, begin - beginBufferZone); if (limit === null) { limit = Number.MAX_VALUE; } me.prefetchEnd = prefetchEnd = Math.min(limit, end + endBufferZone); me.prefetchPages = prefetchPages = pageMap.getPages(prefetchBegin, prefetchEnd); } for (pg in activePages) { page = activePages[pg]; if (prefetchPages) { delete prefetchPages[pg]; } if (activePagesWas && pg in activePagesWas) { delete activePagesWas[pg]; } else { page.adjustLock('active', 1); page.fillRecords(records); } } if (prefetchPages) { for (pg in prefetchPages) { if (prefetchPagesWas && pg in prefetchPagesWas) { delete prefetchPagesWas[pg]; } else { prefetchPages[pg].adjustLock('prefetch', 1); } } } if (prefetchPagesWas) { for (pg in prefetchPagesWas) { adjustingPages.push(prefetchPagesWas[pg]); } if (adjustingPages.length) { me.adjustPageLocks('prefetch', -1); } } if (activePagesWas) { for (pg in activePagesWas) { adjustingPages.push(page = activePagesWas[pg]); page.clearRecords(records); } if (adjustingPages.length) { me.adjustPageLocks('active', -1); } } if (prefetchPages) { pageMap.prioritizePrefetch(direction, pageMap.getPageIndex(begin), pageMap.getPageIndex(end - 1)); } me.lastBegin = begin; me.lastEnd = end; }, onPageDestroy: function(page) { var n = page.number, activePages = this.activePages, prefetchPages = this.prefetchPages; if (activePages) { delete activePages[n]; } if (prefetchPages) { delete prefetchPages[n]; } }, onPageLoad: function(page) { var me = this, callback = me.callback, first, last; if (me.activePages[page.number]) { page.fillRecords(me.records); if (callback) { first = Math.max(me.begin, page.begin); last = Math.min(me.end, page.end); Ext.callback(callback, me.scope, [ me, first, last ]); } } }, pageSortBackFn: function(page1, page2) { return page2.number - page1.number; }, pageSortFwdFn: function(page1, page2) { return page1.number - page2.number; }, refresh: function() { this.records = this.records || {}; }, reload: function() { var me = this, begin = me.begin, end = me.end; me.begin = me.end = 0; me.direction = 1; me.prefetchPages = me.activePages = null; me.goto(begin, end); } } }); Ext.define('Ext.data.virtual.Store', { extend: Ext.data.ProxyStore, alias: 'store.virtual', isVirtualStore: true, config: { data: null, totalCount: null, leadingBufferZone: 200, trailingBufferZone: 50 }, remoteSort: true, remoteFilter: true, sortOnLoad: false, trackRemoved: false, constructor: function(config) { var me = this; me.sortByPage = me.sortByPage.bind(me); me.activeRanges = []; me.pageMap = new Ext.data.virtual.PageMap({ store: me }); me.callParent([ config ]); }, doDestroy: function() { this.pageMap.destroy(); this.callParent(); }, applyGrouper: function(grouper) { this.group(grouper); return this.grouper; }, contains: function(record) { return this.indexOf(record) > -1; }, createActiveRange: function(config) { var range = Ext.apply({ leadingBufferZone: this.getLeadingBufferZone(), trailingBufferZone: this.getTrailingBufferZone(), store: this }, config); return new Ext.data.virtual.Range(range); }, getAt: function(index) { var page = this.pageMap.getPageOf(index, false), ret; if (page && page.records) { ret = page.records[index - page.begin]; } return ret || null; }, getById: function(id) { return this.pageMap.byId[id] || null; }, getCount: function() { return this.totalCount || 0; }, getGrouper: function() { return this.grouper; }, getGroups: function() { var me = this, groups = me.groupCollection; if (!groups) { me.groupCollection = groups = new Ext.util.Collection(); } return groups; }, getSummaryRecord: function() { return this.summaryRecord || null; }, isGrouped: function() { return !!this.grouper; }, group: function(grouper, direction) { var me = this; grouper = grouper || null; if (grouper) { if (typeof grouper === 'string') { grouper = { property: grouper, direction: direction || 'ASC' }; } if (!grouper.isGrouper) { grouper = new Ext.util.Grouper(grouper); } grouper.setRoot('data'); me.getGroups().getSorters().splice(0, 1, { property: 'id', direction: grouper.getDirection() }); } me.grouper = grouper; if (!me.isConfiguring) { me.reload(); me.fireEvent('groupchange', me, grouper); } }, getByInternalId: function(internalId) { return this.pageMap.getByInternalId(internalId); }, indexOf: function(record) { return this.pageMap.indexOf(record); }, indexOfId: function(id) { var rec = this.getById(id); return rec ? this.indexOf(rec) : -1; }, load: function(options) { if (typeof options === 'function') { options = { callback: options }; } var me = this, page = (options && options.page) || 1, pageSize = me.getPageSize(), operation = me.createOperation('read', Ext.apply({ start: (page - 1) * pageSize, limit: pageSize, page: page, filters: me.getFilters().items, sorters: me.getSorters().items, grouper: me.getGrouper() }, options)); operation.execute(); return operation; }, reload: function(options) { if (typeof options === 'function') { options = { callback: options }; } var me = this; if (me.fireEvent('beforereload') === false) { return null; } options = Ext.apply({ internalScope: me, internalCallback: me.handleReload, page: 1 }, options); me.pageMap.clear(); me.getGroups().clear(); return me.load(options); }, removeAll: function() { var activeRanges = this.activeRanges, i; this.pageMap.clear(); for (i = activeRanges.length; i-- > 0; ) { activeRanges[i].reset(); } }, 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(); }, onFilterEndUpdate: function() { var me = this, filters = me.getFilters(false); if (!me.isConfiguring) { me.reload(); me.fireEvent('filterchange', me, filters.getRange()); } }, onSorterEndUpdate: function() { var me = this, sorters = me.getSorters().getRange(), fire = !me.isConfiguring; if (fire) { me.fireEvent('beforesort', me, sorters); } if (fire) { me.reload(); me.fireEvent('sort', me, sorters); } }, updatePageSize: function(pageSize) { var totalCount = this.totalCount; if (totalCount !== null) { this.pageMap.setPageCount(Math.ceil(totalCount / pageSize)); } }, updateTotalCount: function(totalCount, oldTotalCount) { var me = this, pageMap = me.pageMap; me.totalCount = totalCount; pageMap.setPageCount(Math.ceil(totalCount / me.getPageSize())); me.fireEvent('totalcountchange', me, totalCount, oldTotalCount); }, add: function() { Ext.raise('Virtual stores do not support the add() method'); }, insert: function() { Ext.raise('Virtual stores do not support the insert() method'); }, filter: function() { if (!this.getRemoteFilter()) { Ext.raise('Virtual stores do not support local filtering'); } this.callParent(arguments); }, filterBy: function() { Ext.raise('Virtual stores do not support local filtering'); }, loadData: function() { Ext.raise('Virtual stores do not support the loadData() method'); }, applyData: function() { Ext.raise('Virtual stores do not support direct data loading'); }, updateRemoteFilter: function(remoteFilter, oldRemoteFilter) { if (remoteFilter === false) { Ext.raise('Virtual stores are always remotely filtered.'); } this.callParent([ remoteFilter, oldRemoteFilter ]); }, updateRemoteSort: function(remoteSort, oldRemoteSort) { if (remoteSort === false) { Ext.raise('Virtual stores are always remotely sorted.'); } this.callParent([ remoteSort, oldRemoteSort ]); }, updateTrackRemoved: function(value) { if (value !== false) { Ext.raise('Virtual stores do not support trackRemoved.'); } this.callParent(arguments); }, privates: { attachSummaryData: function(resultSet) { var me = this, summary = resultSet.getSummaryData(), grouper, len, i, data, rec; if (summary) { me.summaryRecord = summary; } summary = resultSet.getGroupData(); if (summary) { grouper = me.getGrouper(); if (grouper) { me.groupSummaryData = data = {}; for (i = 0 , len = summary.length; i < len; ++i) { rec = summary[i]; data[grouper.getGroupString(rec)] = rec; } } } }, handleReload: function(op) { var me = this, activeRanges = me.activeRanges, len = activeRanges.length, pageMap = me.pageMap, i, range; if (op.wasSuccessful()) { me.readTotalCount(op.getResultSet()); me.fireEvent('reload', me, op); for (i = 0; i < len; ++i) { range = activeRanges[i]; if (pageMap.canSatisfy(range)) { range.reload(); } } } }, loadVirtualPage: function(page, callback, scope) { var me = this, pageMapGeneration = me.pageMap.generation; return me.load({ page: page.number + 1, internalCallback: function(op) { var resultSet = op.getResultSet(); if (pageMapGeneration === me.pageMap.generation) { if (op.wasSuccessful()) { me.readTotalCount(resultSet); me.attachSummaryData(resultSet); } callback.call(scope || page, op); me.groupSummaryData = null; } } }); }, lockGroups: function(grouper, page) { var groups = this.getGroups(), groupInfo = page.groupInfo = {}, records = page.records, len = records.length, groupSummaryData = this.groupSummaryData, pageMap = this.pageMap, n = page.number, group, i, groupKey, summaryRec, rec, firstRecords, first; for (i = 0; i < len; ++i) { rec = records[i]; groupKey = grouper.getGroupString(rec); if (!groupInfo[groupKey]) { groupInfo[groupKey] = rec; group = groups.get(groupKey); if (!group) { group = new Ext.data.virtual.Group(groupKey); groups.add(group); } firstRecords = group.firstRecords; first = firstRecords[0]; if (first && n < pageMap.getPageIndex(first)) { firstRecords.unshift(rec); } else { firstRecords.push(rec); } summaryRec = groupSummaryData && groupSummaryData[groupKey]; if (summaryRec) { group.summaryRecord = summaryRec; } } } }, onPageDataAcquired: function(page) { var grouper = this.getGrouper(); if (grouper) { this.lockGroups(grouper, page); } }, onPageDestroy: function(page) { var ranges = this.activeRanges, len = ranges.length, i; for (i = 0; i < len; ++i) { ranges[i].onPageDestroy(page); } }, onPageEvicted: function(page) { var grouper = this.getGrouper(); if (grouper) { this.releaseGroups(grouper, page); } }, readTotalCount: function(resultSet) { var total = resultSet.getRemoteTotal(); if (!isNaN(total)) { this.setTotalCount(total); } }, releaseGroups: function(grouper, page) { var groups = this.getGroups(), groupInfo = page.groupInfo, first, firstRecords, key, group; for (key in groupInfo) { first = groupInfo[key]; group = groups.get(key); firstRecords = group.firstRecords; if (firstRecords.length === 1) { groups.remove(group); } else if (firstRecords[0] === first) { firstRecords.shift(); firstRecords.sort(this.sortByPage); } else { Ext.Array.remove(firstRecords, first); } } }, sortByPage: function(rec1, rec2) { var map = this.pageMap; return map.getPageIndex(rec1) - map.getPageIndex(rec2); } } }); 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', parseResponse: function(response) { var text = response && response.responseText; if (text != null) { 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({ parsingError: true, 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.util.TaskRunner', { fireIdleEvent: null, 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 = me.onTick.bind(me); }, newTask: function(config) { var task = new Ext.util.TaskRunner.Task(config); task.manager = this; if (Ext.Timer.track) { task.creator = new Error().stack; } 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, andRemove) { var me = this, tasks = me.tasks, pendingCount = 0, i; if (!task.stopped) { task.stopped = true; task.pending = false; if (task.onStop) { task.onStop.call(task.scope || task, task); } } if (andRemove) { Ext.Array.remove(tasks, task); } for (i = 0; !pendingCount && i < tasks.length; i++) { if (!tasks[i].stopped) { pendingCount++; } } if (!pendingCount) { Ext.undefer(me.timerId); me.timerId = null; } return task; }, stopAll: function(andRemove) { var me = this; Ext.each(this.tasks, function(task) { me.stop(task, andRemove); }, null, true); }, firing: false, nextExpires: 1.0E99, onTick: function() { var me = this, tasks = me.tasks, fireIdleEvent = me.fireIdleEvent, now = Ext.Date.now(), nextExpires = 1.0E99, len = tasks.length, expires, newTasks, i, task, rt, remove, args; var timer = Ext.Timer.get(me.timerId); if (timer) { timer.tasks = []; } 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 (fireIdleEvent === null && task.fireIdleEvent !== false) { fireIdleEvent = true; } task.taskRunCount++; if (task.args) { args = task.addCountToArgs ? task.args.concat([ task.taskRunCount ]) : task.args; } else { args = [ task.taskRunCount ]; } if (timer) { timer.tasks.push(task); } if (me.disableTryCatch) { rt = task.run.apply(task.scope || task, args); } else { try { rt = task.run.apply(task.scope || task, args); } 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 === null) { fireIdleEvent = false; } Ext._suppressIdle = !fireIdleEvent; }, startTimer: function(timeout, now) { var me = this, expires = now + timeout, timerId = me.timerId; if (timerId && me.nextExpires - expires > me.interval) { timerId = Ext.undefer(timerId); } if (!timerId) { if (timeout < me.interval) { timeout = me.interval; } me.timerId = Ext.defer(me.timerFn, timeout); me.nextExpires = expires; var timer = Ext.Timer.get(me.timerId); if (timer) { timer.runner = me; } } } }, 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(andRemove) { this.manager.stop(this, andRemove); }, destroy: function() { this.stop(true); } }); proto = me.Task.prototype; proto.destroy = proto.stop; }); Ext.define('Ext.direct.PollingProvider', { extend: Ext.direct.JsonProvider, alias: 'direct.pollingprovider', 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.stop(true); 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.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() { if (this.pollTask) { this.pollTask.stop(); } }, getInterval: function() { return this.pollTask && this.pollTask.interval; }, setInterval: function(interval) { var me = this, pollTask = me.pollTask; if (interval < 100) { Ext.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, request; 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 { request = { url: url, callback: me.onData, scope: me, params: baseParams, headers: me.getHeaders() }; if (me.timeout != null) { request.timeout = me.timeout; } me.sendAjaxRequest(request); } me.fireEvent('poll', me); } }, onData: function(opt, success, response) { var me = this, i, len, events, event; if (success) { events = me.createEvents(response); for (i = 0 , len = events.length; i < len; ++i) { event = events[i]; me.fireEvent('data', me, event); if (!event.status) { me.fireEvent('exception', me, event); } } } else { event = 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, event); me.fireEvent('exception', me, event); } me.callParent([ opt, success, response ]); }, 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; me.disableBatching = config.batched != null ? !config.batched : false; 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.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.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, paramsAsArray = config.paramsAsArray, metadata = config.metadata, options = config.options, args = [], flatten, i, len; if (me.ordered) { if (me.len > 0) { if (paramOrder) { flatten = config.paramsAsArray && me.len === 1 && (paramOrder.length > 1 || Ext.isArray(params)); if (flatten) { if (Ext.isArray(params)) { for (i = 0 , len = params.length; i < len; i++) { args.push(me.convertParams(params[i], paramOrder, paramOrder.length, true)); } } else { args = me.convertParams(params, paramOrder, paramOrder.length, true); } if (!params.allowSingle || args.length > 1) { args = [ args ]; } } else { args = me.convertParams(params, paramOrder, me.len, false); } } else { 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; }, convertParams: function(params, paramOrder, count, flatten) { var ret = [], paramName, i, len; for (i = 0 , len = count; i < len; i++) { paramName = paramOrder[i]; ret.push(params[paramName]); } if (flatten) { return ret.length === 0 ? undefined : ret.length === 1 ? ret[0] : ret; } else { return ret; } }, 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.raise('options.metadata is not an Array ' + 'for Ext Direct method ' + me.name); } else if (options.metadata.length < me.metadata.len) { Ext.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.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.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', 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', type: 'remoting', enableBuffer: 10, bufferLimit: Number.MAX_VALUE, maxRetries: 1, constructor: function(config) { var me = this; me.callParent([ config ]); me.namespace = (Ext.isString(me.namespace)) ? Ext.ns(me.namespace) : me.namespace || Ext.global; me.callBuffer = []; }, destroy: function() { if (this.callTask) { this.callTask.cancel(); } this.callParent(); }, connect: function() { var me = this; if (!me.url) { Ext.raise('Error initializing RemotingProvider "' + me.id + '", no url configured.'); } me.callParent(); }, 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, handler; handler = function() { me.invokeFunction(action, method, Array.prototype.slice.call(arguments, 0)); }; handler.name = handler.$name = action + '.' + method.name; handler.$directFn = true; handler.directCfg = handler.$directCfg = { action: action, method: method }; return handler; }, invokeFunction: function(action, method, args) { var me = this, transaction, form, isUpload, postParams; transaction = me.configureTransaction(action, method, args); if (me.fireEvent('beforecall', me, transaction, method) !== false) { Ext.direct.Manager.addTransaction(transaction); if (transaction.isForm) { 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.queueTransaction(transaction); me.fireEvent('call', me, transaction, method); } }, 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.raise("Callback argument is not a function " + "for Ext Direct method " + action + "." + method.name); } cb = cb && scope ? cb.bind(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: !!method.formHandler, disableBatching: method.disableBatching }); if (options && options.timeout != null) { params.timeout = options.timeout; } return new Ext.direct.Transaction(params); }, queueTransaction: function(transaction) { var me = this, callBuffer = me.callBuffer, enableBuffer = me.enableBuffer; if (transaction.isForm || enableBuffer === false || transaction.disableBatching || transaction.timeout != null) { me.sendTransaction(transaction); return; } callBuffer.push(transaction); if (enableBuffer && callBuffer.length < me.bufferLimit) { 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.sendTransaction(len === 1 ? buffer[0] : buffer); me.callBuffer = []; } }, sendTransaction: 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, headers: me.getHeaders() }; if (transaction.timeout != null) { request.timeout = transaction.timeout; } else if (me.timeout != null) { request.timeout = me.timeout; } if (transaction.isForm) { Ext.apply(request, { params: transaction.params, form: transaction.form, isUpload: transaction.isUpload }); } else { 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; } } return me.sendAjaxRequest(request); }, 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; }, onData: function(options, success, response) { var me = this, i, len, events, event, transaction, transactions; if (me.destroying || me.destroyed) { return; } events = success && me.createEvents(response); success = events && events.length && !events[0].parsingError; if (success) { for (i = 0 , len = events.length; i < len; ++i) { event = events[i]; me.fireEvent('data', me, event); transaction = me.getTransaction(event); if (transaction) { if (me.fireEvent('beforecallback', me, event, transaction) !== false) { me.runCallback(transaction, event, true); } Ext.direct.Manager.removeTransaction(transaction); } } } else { transactions = [].concat(options.transaction); event = events[0] || new Ext.direct.ExceptionEvent({ data: null, transaction: transaction, code: Ext.direct.Manager.exceptions.TRANSPORT, message: 'Unable to connect to the server.', xhr: response }); for (i = 0 , len = transactions.length; i < len; ++i) { transaction = me.getTransaction(transactions[i]); if (transaction && transaction.retryCount < me.maxRetries) { transaction.retry(); } else { me.fireEvent('data', me, event); me.fireEvent('exception', me, event); if (transaction && me.fireEvent('beforecallback', me, event, transaction) !== false) { me.runCallback(transaction, event, false); } Ext.direct.Manager.removeTransaction(transaction); } } } me.callParent([ options, success, response ]); }, getTransaction: function(options) { return options && options.tid ? Ext.direct.Manager.getTransaction(options.tid) : null; }, 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 ]); } } }, inheritableStatics: { checkConfig: function(config) { return config && config.type === 'remoting' && config.url && Ext.isArray(config.actions); } } }); 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, data; if (!dom) { return me.detach(); } me.dom = Ext.getDom(dom); if (!Ext.cache[dom.id]) { data = me.peekData(); if (data) { data.isSynchronized = false; } } return me; }, detach: function() { return (this.dom = null); }, addListener: function() { Ext.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.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 = {}, detachedBodyEl; Fly.cache = flyweights; Ext.fly = function(dom, named) { var fly = null, fn = Ext.fly, nodeType, data; named = named || (fn.caller && (fn.caller.$name || 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) { if (named === 'constructor') { named = '$constructor'; } fly = flyweights[named] || (flyweights[named] = new Fly()); fly.dom = dom; data = fly.peekData(); if (data) { data.isSynchronized = false; } } } } return fly; }; Ext.getDetachedBody = function() { if (!detachedBodyEl) { Ext.detachedBodyEl = detachedBodyEl = new Fly(document.createElement('div')); detachedBodyEl.isDetachedBody = true; } return detachedBodyEl; }; }); Ext.define('Ext.dom.CompositeElementLite', { alternateClassName: [ 'Ext.CompositeElementLite' ], 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() { this.invoke('destroy', arguments); this.callParent(); } }, function(CompositeElementLite) { var prototype = CompositeElementLite.prototype; CompositeElementLite.importElementMethods(); prototype.on = prototype.addListener; }); 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.define('Ext.dom.GarbageCollector', { singleton: true, interval: 30000, constructor: function() { var me = this; me.lastTime = Ext.now(); me.onTick = me.onTick.bind(me); me.onTick.$skipTimerCheck = true; 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.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) { isGarbage = false; 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; }, onTick: function() { this.timerId = null; if (Ext.enableGarbageCollector) { this.collect(); } this.resume(); }, pause: function() { var timerId = this.timerId; if (timerId) { this.timerId = null; Ext.undefer(timerId); } }, resume: function() { var me = this, lastTime = me.lastTime; if (Ext.enableGarbageCollector && (Ext.now() - lastTime) > me.interval) { me.collect(); } if (!me.timerId) { me.timerId = Ext.defer(me.onTick, me.interval); } } }); Ext.define('Ext.dom.TouchAction', { singleton: true, lastTouchStartTime: 0, minMoveDistance: 8, spaceRe: /\s+/, preventSingle: null, preventMulti: null, disabledOverflowDom: null, panXCls: Ext.baseCSSPrefix + 'touch-action-pan-x', panYCls: Ext.baseCSSPrefix + 'touch-action-pan-y', cssValues: [ 'none', 'pan-x', 'pan-y', 'pan-x pan-y', 'pinch-zoom', 'pan-x pinch-zoom', 'pan-y pinch-zoom', 'pan-x pan-y pinch-zoom', 'double-tap-zoom', 'pan-x double-tap-zoom', 'pan-y double-tap-zoom', 'pan-x pan-y double-tap-zoom', 'pinch-zoom double-tap-zoom', 'pan-x pinch-zoom double-tap-zoom', 'pan-y pinch-zoom double-tap-zoom', '' ], objectValues: [ { panX: false, panY: false, pinchZoom: false, doubleTapZoom: false }, { panX: true, panY: false, pinchZoom: false, doubleTapZoom: false }, { panX: false, panY: true, pinchZoom: false, doubleTapZoom: false }, { panX: true, panY: true, pinchZoom: false, doubleTapZoom: false }, { panX: false, panY: false, pinchZoom: true, doubleTapZoom: false }, { panX: true, panY: false, pinchZoom: true, doubleTapZoom: false }, { panX: false, panY: true, pinchZoom: true, doubleTapZoom: false }, { panX: true, panY: true, pinchZoom: true, doubleTapZoom: false }, { panX: false, panY: false, pinchZoom: false, doubleTapZoom: true }, { panX: true, panY: false, pinchZoom: false, doubleTapZoom: true }, { panX: false, panY: true, pinchZoom: false, doubleTapZoom: true }, { panX: true, panY: true, pinchZoom: false, doubleTapZoom: true }, { panX: false, panY: false, pinchZoom: true, doubleTapZoom: true }, { panX: true, panY: false, pinchZoom: true, doubleTapZoom: true }, { panX: false, panY: true, pinchZoom: true, doubleTapZoom: true }, { panX: true, panY: true, pinchZoom: true, doubleTapZoom: true } ], attributeName: 'data-extTouchAction', constructor: function() { var me = this, supports = Ext.supports; if (supports.TouchAction) { me.cssProp = 'touch-action'; } else if (supports.MSPointerEvents) { me.cssProp = '-ms-touch-action'; } if (supports.TouchEvents) { Ext.getWin().on({ touchstart: 'onTouchStart', touchmove: 'onTouchMove', touchend: 'onTouchEnd', scope: me, delegated: false, translate: false, capture: true, priority: 5000 }); Ext.on({ scroll: 'onScroll', scope: me, destroyable: true }); } if (Ext.isFunction(Object.freeze)) { var objectValues = me.objectValues; for (var i = 0, ln = objectValues.length; i < ln; i++) { Object.freeze(objectValues[i]); } } }, containsTargets: function(dom, e) { var contains = true, event = e.browserEvent, touches = e.type === 'touchend' ? event.changedTouches : event.touches, i, ln; for (i = 0 , ln = touches.length; i < ln; i++) { if (!dom.contains(touches[i].target)) { contains = false; break; } } return contains; }, disableOverflow: function(dom, vertical) { var me = this, overflowName = vertical ? 'overflow-y' : 'overflow-x', overflowStyle, cls; if (!me.disabledOverflowDom && !Ext.isiOS && !Ext.getScrollbarSize().width) { me.disabledOverflowDom = dom; cls = vertical ? me.panXCls : me.panYCls; while (dom) { overflowStyle = Ext.fly(dom).getStyle(overflowName); if (overflowStyle === 'auto' || overflowStyle === 'scroll') { Ext.fly(dom).addCls(cls); } dom = dom.parentNode; } } }, get: function(dom) { var flags = dom.getAttribute(this.attributeName), ret = null; if (flags != null) { ret = this.objectValues[flags]; } return ret; }, getFlags: function(touchAction) { var flags; if (typeof touchAction === 'number') { flags = touchAction; } else { flags = 0; if (touchAction.panX !== false) { flags |= 1; } if (touchAction.panY !== false) { flags |= 2; } if (touchAction.pinchZoom !== false) { flags |= 4; } if (touchAction.doubleTapZoom !== false) { flags |= 8; } } return flags; }, isScrollable: function(el, vertical, forward) { var overflowStyle = Ext.fly(el).getStyle(vertical ? 'overflow-y' : 'overflow-x'), isScrollable = (overflowStyle === 'auto' || overflowStyle === 'scroll'); if (isScrollable) { if (vertical) { isScrollable = forward ? (el.scrollTop + el.clientHeight) < el.scrollHeight : el.scrollTop > 0; } else { isScrollable = forward ? (el.scrollLeft + el.clientWidth) < el.scrollWidth : el.scrollLeft > 0; } } return isScrollable; }, lookupFlags: function(dom) { return parseInt((dom.getAttribute && dom.getAttribute(this.attributeName)) || 15, 10); }, onScroll: function() { this.scrollOccurred = true; this.isDoubleTap = false; }, onTouchEnd: function(e) { var me = this, dom = e.target, touchCount, flags, doubleTapZoom; touchCount = e.browserEvent.touches.length; if (touchCount === 0) { if (me.isDoubleTap) { while (dom) { flags = me.lookupFlags(dom); if (flags != null) { doubleTapZoom = flags & 8; if (!doubleTapZoom) { e.preventDefault(); } } dom = dom.parentNode; } } me.isDoubleTap = false; me.preventSingle = null; me.preventMulti = null; me.resetOverflow(); } }, onTouchMove: function(e) { var me = this, prevent = null, dom = e.target, flags, touchCount, panX, panY, point, startPoint, isVertical, scale, distance, deltaX, deltaY, preventSingle, preventMulti; preventSingle = me.preventSingle; preventMulti = me.preventMulti; touchCount = e.browserEvent.touches.length; if ((touchCount === 1 && (preventSingle === false)) || (preventMulti === false)) { return; } if ((touchCount > 1 && (preventMulti === true)) || (touchCount === 1 && (preventSingle === true))) { prevent = true; } else { if (touchCount === 1) { point = e.getPoint(); startPoint = me.startPoint; scale = Ext.Element.getViewportScale(); distance = point.getDistanceTo(me.startPoint) * scale; deltaX = point.x - startPoint.x; deltaY = point.y - startPoint.y; isVertical = Math.abs(deltaY) >= Math.abs(deltaX); } while (dom && (dom.nodeType === 1)) { flags = me.lookupFlags(dom); if (flags & 0) { prevent = true; } else if (touchCount === 1) { panX = !!(flags & 1); panY = !!(flags & 2); if (panX && panY) { prevent = false; } else if (!panX && !panY) { prevent = true; } else if (distance >= me.minMoveDistance) { prevent = !!((panX && isVertical) || (panY && !isVertical)); } if (!prevent && me.isScrollable(dom, isVertical, (isVertical ? deltaY : deltaX) < 0)) { break; } } else if (me.containsTargets(dom, e)) { prevent = !(flags & 4); } else { prevent = false; } if (prevent) { break; } dom = dom.parentNode; } } if (touchCount === 1) { me.preventSingle = prevent; } else if (touchCount > 1) { me.preventMulti = prevent; } if (prevent) { e.preventDefault(); } }, onTouchStart: function(e) { var me = this, time, flags, dom, panX, panY; if (e.browserEvent.touches.length === 1) { time = e.time; if (!me.scrollOccurred && ((time - me.lastTouchStartTime) <= 500)) { me.isDoubleTap = true; } me.lastTouchStartTime = time; me.scrollOccurred = false; me.startPoint = e.getPoint(); dom = e.target; while (dom) { flags = me.lookupFlags(dom); if (flags != null) { panX = !!(flags & 1); panY = !!(flags & 2); if (panX !== panY) { me.disableOverflow(dom, panX); break; } } dom = dom.parentNode; } } else { me.isDoubleTap = false; } }, resetOverflow: function() { var me = this, dom = me.disabledOverflowDom; while (dom) { Ext.fly(dom).removeCls([ me.panXCls, me.panYCls ]); dom = dom.parentNode; } me.disabledOverflowDom = null; }, set: function(dom, value) { var me = this, cssProp = me.cssProp, flags = me.getFlags(value), supportedFlags = (flags & Ext.supports.TouchAction), attributeName = me.attributeName; if (cssProp) { Ext.fly(dom).setStyle(cssProp, me.cssValues[supportedFlags]); } if (flags === 15) { dom.removeAttribute(attributeName); } else { dom.setAttribute(attributeName, flags); } } }); Ext.define('Ext.drag.Constraint', { alias: 'drag.constraint.base', mixins: [ Ext.mixin.Factoryable ], factoryConfig: { defaultType: 'base', type: 'drag.constraint' }, config: { element: null, horizontal: null, region: null, snap: null, source: null, vertical: null, x: null, y: null }, constructor: function(config) { this.initConfig(config); }, applyElement: function(element) { if (element && typeof element !== 'boolean') { element = Ext.get(element); } return element || null; }, applySnap: function(snap) { if (typeof snap === 'number') { snap = { x: snap, y: snap }; } return snap; }, constrain: function(xy, info) { var me = this, x = xy[0], y = xy[1], constrainInfo = me.constrainInfo, initial = constrainInfo.initial, constrainX = constrainInfo.x, constrainY = constrainInfo.y, snap = constrainInfo.snap, min, max; if (!constrainInfo.vertical) { if (snap && snap.x) { if (snap.xFn) { x = snap.x.call(me, info, x); } else { x = me.doSnap(x, initial.x, snap.x); } } if (constrainX) { min = constrainX[0]; max = constrainX[1]; if (min !== null && x < min) { x = min; } if (max !== null && x > max) { x = max; } } } else { x = initial.x; } if (!constrainInfo.horizontal) { if (snap && snap.y) { if (snap.yFn) { y = snap.y.call(me, info, y); } else { y = me.doSnap(y, initial.y, snap.y); } } if (constrainY) { min = constrainY[0]; max = constrainY[1]; if (min !== null && y < min) { y = min; } if (max !== null && y > max) { y = max; } } } else { y = initial.y; } return [ x, y ]; }, destroy: function() { this.setSource(null); this.setElement(null); this.callParent(); }, privates: { constrainValue: function(a, b, resolver) { var val = null, aNull = a === null, bNull = b === null; if (!(aNull && bNull)) { if (aNull) { val = b; } else if (bNull) { val = a; } else { val = resolver(a, b); } } return val; }, doSnap: function(position, initial, snap) { if (!snap) { return position; } var ratio = (position - initial) / snap, floor = Math.floor(ratio); if (ratio - floor <= 0.5) { ratio = floor; } else { ratio = floor + 1; } return initial + (snap * ratio); }, onDragStart: function(info) { var me = this, snap = me.getSnap(), vertical = !!me.getVertical(), horizontal = !!me.getHorizontal(), element = me.getElement(), region = me.getRegion(), proxy = info.proxy, proxyEl = proxy.element, x = me.getX(), y = me.getY(), minX = null, maxX = null, minY = null, maxY = null, rminX = null, rmaxX = null, rminY = null, rmaxY = null, pos, size; if (element) { if (typeof element === 'boolean') { element = me.getSource().getElement().parent(); } if (info.local) { pos = element.getStyle('position'); if (pos === 'relative' || pos === 'absolute') { size = element.getSize(); region = new Ext.util.Region(0, size.width, size.height, 0); } else { region = element.getRegion(true, true); } } else { region = element.getRegion(true); } } if (region) { if (!vertical) { rminX = region.left; rmaxX = region.right - (proxyEl ? proxy.width : 0); } if (!horizontal) { rminY = region.top; rmaxY = region.bottom - (proxyEl ? proxy.height : 0); } } if (!vertical && (region || x)) { if (x) { minX = x[0]; maxX = x[1]; } if (minX !== null || maxX !== null || rminX !== null || rmaxX !== null) { minX = me.constrainValue(minX, rminX, Math.max); maxX = me.constrainValue(maxX, rmaxX, Math.min); x = [ minX, maxX ]; } } if (!horizontal && (region || y)) { if (y) { minY = y[0]; maxY = y[1]; } if (minY !== null || maxY !== null || rminY !== null || rmaxY !== null) { minY = me.constrainValue(minY, rminY, Math.max); maxY = me.constrainValue(maxY, rmaxY, Math.min); y = [ minY, maxY ]; } } if (snap) { snap = { x: snap.x, xFn: typeof snap.x === 'function', y: snap.y, yFn: typeof snap.y === 'function' }; } me.constrainInfo = { initial: info.element.initial, vertical: vertical, horizontal: horizontal, x: x, y: y, snap: snap }; } } }); Ext.define('Ext.drag.Info', { constructor: function(source, e) { if (!source) { return; } var me = this, local = source.getLocal(), el, proxyEl, proxy, x, xy, y, pageXY, elPageXY; me.source = source; me.local = local; xy = me.getEventXY(e); pageXY = e.getXY(); el = source.getElement(); elPageXY = el.getXY(); xy = local ? el.getLocalXY() : elPageXY; x = xy[0]; y = xy[1]; me.initialEvent = e; me.eventTarget = e.target; me.cursor = { current: { x: x, y: y }, delta: { x: 0, y: 0 }, initial: { x: pageXY[0], y: pageXY[1] }, offset: { x: pageXY[0] - elPageXY[0], y: pageXY[1] - elPageXY[1] } }; me.element = { current: { x: x, y: y }, delta: { x: 0, y: 0 }, initial: { x: x, y: y } }; me.proxy = { instance: source.getProxy(), current: { x: x, y: y }, delta: { x: 0, y: 0 }, initial: { x: x, y: y }, element: el, isUnderCursor: false, isElement: true }; me.types = []; me.data = {}; source.describe(me); proxy = me.proxy; proxyEl = proxy.instance.setupElement(me); proxy.isElement = proxyEl === source.getElement(); proxy.element = proxyEl; if (proxyEl) { proxy.width = proxyEl.getWidth(); proxy.height = proxyEl.getHeight(); } if (proxy.isElement) { el = me.element; el.current = proxy.current; el.delta = proxy.delta; } me.needsCursorCheck = proxy.element && source.manager && source.manager.pointerBug; }, cursor: null, element: null, eventTarget: null, files: null, isNative: false, proxy: null, source: null, target: null, types: null, valid: false, clearData: function(type) { Ext.Array.remove(this.types, type); delete this.data[type]; }, clone: function() { var me = this, ret = new Ext.drag.Info(); ret.cursor = Ext.merge({}, me.cursor); ret.data = Ext.apply({}, me.data); ret.element = Ext.merge({}, me.element); ret.eventTarget = me.eventTarget; ret.proxy = Ext.merge({}, me.proxy); ret.source = me.source; ret.target = me.target; ret.types = Ext.Array.clone(me.types); ret.valid = me.valid; return ret; }, getData: function(type) { var me = this, data = me.data, dt = me.dataTransfer, ret; if (dt) { ret = dt.getData(type); } else { if (!me.finalized) { Ext.raise('Unable to call getData until the drop is complete'); } ret = data[type]; if (typeof ret === 'function') { data[type] = ret = ret.call(me.source, me); } if (!ret && ret !== 0) { ret = ''; } } return Ext.Promise.resolve(ret); }, setData: function(type, value) { Ext.Array.include(this.types, type); this.data[type] = value; }, destroy: function() { var me = this; me.eventTarget = me.data = me.proxy = me.targetMap = me.targetMap = me.types = me.elementMap = me.possibleTargets = me.target = null; me.callParent(); }, privates: { data: null, dataTransfer: null, elementMap: null, possibleTargets: null, targetMap: null, copyNativeData: function(target, e) { var dt = e.browserEvent.dataTransfer; this.target = target; this.dataTransfer = dt; this.files = dt.files; }, finalize: function() { var me = this, target = me.target; me.finalized = true; if (target) { target.info = null; target.handleDrop(me); } }, getAlignXY: function(x, y) { var me = this, source = me.source, cursorOffset = me.cursor.offset, proxy = source.getProxy(), proxyEl = me.proxy.element, constrain = source.getConstrain(), xy = [ x, y ]; if (proxyEl) { if (me.proxy.isElement) { xy[0] -= cursorOffset.x; xy[1] -= cursorOffset.y; } else { xy = proxy.adjustCursorOffset(me, xy); } if (constrain) { xy = constrain.constrain(xy, me); } } return xy; }, getEventXY: function(e) { var xy = e.getXY(), source = this.source; if (this.local) { xy = source.convertToLocalXY(xy); } return xy; }, onNativeDragEnter: function(target, e) { var me = this; me.valid = target.accepts(me); target.info = me; me.copyNativeData(target, e); }, onNativeDragLeave: function(target, e) { var me = this; if (me.target === target) { target.info = null; me.valid = false; me.target = me.dataTransfer = me.files = null; } }, onNativeDragMove: function(target, e) { this.copyNativeData(target, e); }, onNativeDrop: function(target, e) { this.copyNativeData(target, e); target.info = null; }, setActive: function(target) { var me = this, source = me.source, current = me.target, changed = current !== target; if (current && changed) { current.handleDragLeave(me); current.info = null; } me.target = target; if (target) { if (changed) { me.valid = !!me.possibleTargets[target.getId()] && target.accepts(me) !== false; target.handleDragEnter(me); target.info = me; } target.handleDragMove(me); } else { me.valid = false; } if (changed) { source.getProxy().update(me); } }, update: function(event, beforeStart) { var me = this, xy = me.getEventXY(event), x = xy[0], y = xy[1], alignXY = me.getAlignXY(x, y), alignX = alignXY[0], alignY = alignXY[1], proxyData = me.proxy, cursor = me.cursor, current = cursor.current, delta = cursor.delta, initial = cursor.initial, proxy = proxyData.instance; current.x = x; current.y = y; delta.x = x - initial.x; delta.y = y - initial.y; current = proxyData.current; delta = proxyData.delta; initial = proxyData.initial; current.x = alignX; current.y = alignY; delta.x = alignX - initial.x; delta.y = alignY - initial.y; if (me.needsCursorCheck) { proxyData.isUnderCursor = !(x < alignX || y < alignY || x > proxyData.width + alignX || y > proxyData.height + alignY); } if (!beforeStart && proxy) { proxy.setXY(me, alignXY); } } } }); Ext.define('Ext.drag.Item', { mixins: [ Ext.mixin.Observable, Ext.mixin.Identifiable ], config: { autoDestroy: true, component: null, element: null, groups: null }, constructor: function(config) { this.mixins.observable.constructor.call(this, config); }, isDisabled: function() { return this.disabled; }, disable: function() { this.disabled = true; }, enable: function() { this.disabled = false; }, updateComponent: function(comp, was) { var el; if (comp) { el = comp.el; } else if (was && was.el === this.getElement()) { el = null; } else { return; } this.setElement(el); }, applyElement: function(element) { return element ? Ext.get(element) : null; }, updateElement: function() { this.setupListeners(); }, applyGroups: function(group) { if (typeof group === 'string') { group = [ group ]; } return group; }, destroy: function() { var me = this, el = me.getElement(); me.destroying = true; me.setElement(null); if (el && me.getAutoDestroy()) { el.destroy(); } me.callParent(); me.destroying = false; }, privates: { disabled: false, convertToLocalXY: function(xy) { var c = this.getComponent(); if (c) { xy = c.convertToLocalXY(xy); } else { xy = this.getElement().translateXY(xy[0], xy[1]); xy = [ xy.x, xy.y ]; } return xy; }, getElListeners: Ext.privateFn, setupListeners: function(element) { var me = this, elListeners = me.elListeners; element = element || me.getElement(); if (elListeners) { elListeners.destroy(); me.elListeners = null; } if (element) { me.elListeners = element.on(Ext.apply({ scope: me, destroyable: true }, me.getElListeners())); } } } }); Ext.define('Ext.drag.Manager', { singleton: true, dragCls: Ext.baseCSSPrefix + 'drag-body', pointerBug: Ext.isTouch || (!Ext.supports.CSSPointerEvents || Ext.isIE10m || Ext.isOpera), constructor: function() { this.targets = {}; this.nativeTargets = []; Ext.onReady(this.init, this); }, init: function() { Ext.getDoc().on({ scope: this, dragenter: { capture: true, fn: 'onNativeDragEnter' }, dragleave: 'onNativeDragLeave', dragover: 'onNativeDragOver', drop: 'onNativeDrop' }); }, destroy: function() { var me = this, targets = me.targets, key; me.destroying = true; for (key in targets) { targets[key].destroy(); } me.targets = null; me.callParent(); me.destroying = false; }, privates: { elementFromPoint: function(x, y) { if (Ext.rootInheritedState.rtl) { x = Ext.Element.getViewportWidth() - x; } return Ext.dom.Element.fromPagePoint(x, y, true); }, getAtPoint: function(info) { var current = info.cursor.current, elementMap = info.elementMap, isUnderCursor = info.proxy.isUnderCursor, proxyEl = this.pointerBug && isUnderCursor ? info.proxy.element.dom : null, target, el; if (proxyEl) { proxyEl.style.visibility = 'hidden'; } el = this.elementFromPoint(current.x, current.y); if (proxyEl) { proxyEl.style.visibility = 'visible'; } while (el) { target = elementMap[el.id]; if (target) { return target; } el = el.parentNode; } return null; }, getNativeDragInfo: function(e) { var info = this.nativeDragInfo; if (!info) { this.nativeDragInfo = info = new Ext.drag.Info(); info.isNative = true; } return info; }, onDragCancel: function() { Ext.getBody().removeCls(this.dragCls); }, onDragEnd: function(info, e) { info.finalize(); Ext.getBody().removeCls(this.dragCls); }, onDragMove: function(info, e) { this.processDrag(info); }, onDragStart: function(info, e) { var me = this, source = info.source, targets = me.targets, groups = source.getGroups(), targetMap = {}, possibleTargets = {}, elementMap = {}, id, target, targetGroups, groupMap, groupOk, len, i; elementMap = {}; possibleTargets = {}; if (groups) { groupMap = Ext.Array.toMap(groups); } for (id in targets) { target = targets[id]; if (!target.isDisabled()) { groupOk = false; targetGroups = target.getGroups(); if (!groupMap && !targetGroups) { groupOk = true; } else if (groupMap && targetGroups) { for (i = 0 , len = targetGroups.length; i < len; ++i) { if (groupMap[targetGroups[i]]) { groupOk = true; break; } } } if (groupOk) { possibleTargets[id] = target; } } targetMap[id] = target; elementMap[target.getElement().id] = target; } info.possibleTargets = possibleTargets; info.targetMap = targetMap; info.elementMap = elementMap; Ext.getBody().addCls(me.dragCls); me.processDrag(info); }, onNativeDragEnter: function(e) { var nativeTargets = this.nativeTargets, target = e.target; e.preventDefault(); if (nativeTargets[nativeTargets.length - 1] !== target) { nativeTargets.push(target); } }, onNativeDragLeave: function(e) { var nativeTargets = this.nativeTargets; Ext.Array.remove(nativeTargets, e.target); if (nativeTargets.length === 0) { this.nativeDragInfo = null; } }, onNativeDragOver: function(e) { e.preventDefault(); }, onNativeDrop: function(e) { e.preventDefault(); this.nativeTargets.length = 0; this.nativeDragInfo = null; }, processDrag: function(info) { info.setActive(this.getAtPoint(info)); }, register: function(target) { this.targets[target.getId()] = target; }, unregister: function(target) { if (this.destroying) { return; } delete this.targets[target.getId()]; } } }); Ext.define('Ext.drag.Source', { extend: Ext.drag.Item, defaultIdPrefix: 'source-', config: { activateOnLongPress: false, activeCls: null, constrain: null, handle: null, local: null, proxy: 'original', revert: false }, dragging: false, constructor: function(config) { var describe = config && config.describe; if (describe) { this.describe = describe; config = Ext.apply({}, config); delete config.describe; } this.callParent([ config ]); this.manager = Ext.drag['Manager']; }, describe: Ext.emptyFn, isDragging: function() { return this.dragging; }, beforeDragStart: Ext.emptyFn, onDragCancel: Ext.emptyFn, onDragEnd: Ext.emptyFn, onDragMove: Ext.emptyFn, onDragStart: Ext.emptyFn, applyActivateOnLongPress: function(activateOnLongPress) { if (typeof activateOnLongPress === 'string') { activateOnLongPress = [ activateOnLongPress ]; } return activateOnLongPress; }, updateActivateOnLongPress: function(activateOnLongPress) { if (!this.isConfiguring) { this.setupListeners(); } }, updateActiveCls: function(cls, oldCls) { if (this.dragging) { var el = this.getElement(); el.replaceCls(oldCls, cls); } }, applyConstrain: function(constrain) { if (constrain && !constrain.$isClass) { if (constrain.isRegion) { constrain = { region: constrain }; } else if (constrain.isElement || !Ext.isObject(constrain)) { constrain = { element: constrain }; } constrain = Ext.apply({ source: this }, constrain); constrain = Ext.Factory.dragConstraint(constrain); } return constrain; }, updateElement: function(element, oldElement) { if (oldElement && !oldElement.destroyed) { oldElement.un('dragstart', 'stopNativeDrag', this); } if (element && !this.getHandle()) { element.setTouchAction({ panX: false, panY: false }); element.on('dragstart', 'stopNativeDrag', this, { translate: false, delegated: false }); } this.callParent([ element, oldElement ]); }, updateHandle: function() { if (!this.isConfiguring) { this.setupListeners(); } }, applyProxy: function(proxy) { if (proxy) { proxy = Ext.Factory.dragproxy(proxy); } return proxy; }, updateProxy: function(proxy, oldProxy) { if (oldProxy) { oldProxy.destroy(); } if (proxy) { proxy.setSource(this); } }, resolveListenerScope: function() { var ownerCmp = this.ownerCmp, a = arguments; if (ownerCmp) { return ownerCmp.resolveListenerScope.apply(ownerCmp, a); } return this.callParent(a); }, destroy: function() { var me = this; me.manager = me.initialEvent = null; me.setConstrain(null); me.setProxy(null); me.callParent(); }, privates: { draggingCls: Ext.baseCSSPrefix + 'drag-dragging', info: null, revertCls: Ext.baseCSSPrefix + 'drag-revert', canActivateOnLongPress: function(e) { var activate = this.getActivateOnLongPress(); return !!(activate && (activate === true || Ext.Array.contains(activate, e.pointerType))); }, dragCleanup: function(info) { var me = this, cls = me.getActiveCls(), proxy = me.getProxy(), el = me.getElement(), proxyEl = info ? info.proxy.element : null; if (cls) { el.removeCls(cls); } if (proxyEl) { proxyEl.removeCls(me.draggingCls); } proxy.cleanup(info); me.dragging = false; me.initialEvent = me.info = null; }, getElListeners: function() { var o = { touchstart: 'handleTouchStart', dragstart: 'handleDragStart', drag: 'handleDragMove', dragend: 'handleDragEnd', dragcancel: 'handleDragCancel' }, handle = this.getHandle(); if (handle) { o.dragstart = { fn: o.dragstart, delegate: handle }; } if (this.getActivateOnLongPress()) { o.longpress = 'handleLongPress'; } return o; }, handleDragCancel: function(e) { var me = this, info = me.info, manager = me.manager; if (manager) { manager.onDragCancel(info, e); } me.onDragCancel(info); if (me.hasListeners.dragcancel) { me.fireEvent('dragcancel', me, info, e); } Ext.fireEvent('dragcancel', me, info, e); me.dragCleanup(info); }, handleDragEnd: function(e) { if (!this.dragging) { return; } var me = this, manager = me.manager, revert = me.getRevert(), info = me.info, proxy = info.proxy; info.update(e); if (manager) { manager.onDragEnd(info, e); } me.onDragEnd(info); if (me.hasListeners.dragend) { me.fireEvent('dragend', me, info, e); } Ext.fireEvent('dragend', me, info, e); proxy = proxy.instance; if (revert && proxy) { proxy.dragRevert(info, me.revertCls, revert, function() { me.dragCleanup(info); }); } else { me.dragCleanup(info); } }, handleDragMove: function(e) { var me = this, info = me.info, manager = me.manager; if (!me.dragging) { return; } e.stopPropagation(); e.claimGesture(); info.update(e); if (manager) { manager.onDragMove(info, e); } me.onDragMove(info); if (me.hasListeners.dragmove) { me.fireEvent('dragmove', me, info, e); } }, handleDragStart: function(e) { var me = this, hasListeners = me.hasListeners, manager = me.manager, constrain = me.getConstrain(), initialEvent = me.initialEvent, el, cls, info, cancel, proxyEl; if (me.preventStart(e)) { return false; } if (hasListeners.initdragconstraints) { me.fireEvent('initdragconstraints', me, e); } me.info = info = new Ext.drag.Info(me, initialEvent); me.setup(info); if (constrain) { constrain.onDragStart(info); } info.update(e, true); cancel = me.beforeDragStart(info) === false; if (!cancel && hasListeners.beforedragstart) { cancel = me.fireEvent('beforedragstart', me, info, e) === false; } if (cancel) { me.dragCleanup(); return false; } e.claimGesture(); me.dragging = true; cls = me.getActiveCls(); el = me.getElement(); if (cls) { el.addCls(cls); } proxyEl = info.proxy.element; if (proxyEl) { proxyEl.addCls(me.draggingCls); } info.update(e); if (manager) { manager.onDragStart(info, e); } me.onDragStart(info); if (hasListeners.dragstart) { me.fireEvent('dragstart', me, info, e); } Ext.fireEvent('dragstart', me, info, e); }, handleLongPress: function(e) { if (!this.isDisabled() && this.canActivateOnLongPress(e)) { this.initialEvent = e; e.startDrag(); } }, handleTouchStart: function(e) { if (!this.isDisabled()) { this.initialEvent = e; } }, preventStart: function(e) { return this.isDisabled() || (!e.longpress && this.canActivateOnLongPress(e)); }, setup: Ext.privateFn, stopNativeDrag: function(e) { e.preventDefault(); } } }); Ext.define('Ext.drag.Target', { extend: Ext.drag.Item, defaultIdPrefix: 'target-', config: { invalidCls: '', validCls: '' }, constructor: function(config) { var me = this, accepts = config && config.accepts; if (accepts) { me.accepts = accepts; config = Ext.apply({}, config); delete config.accepts; } me.callParent([ config ]); Ext.drag.Manager.register(me); }, accepts: function(info) { return true; }, disable: function() { this.callParent(); this.setupListeners(null); }, enable: function() { this.callParent(); this.setupListeners(); }, beforeDrop: Ext.emptyFn, onDrop: Ext.emptyFn, onDragEnter: Ext.emptyFn, onDragLeave: Ext.emptyFn, onDragMove: Ext.emptyFn, updateInvalidCls: function(invalidCls, oldInvalidCls) { var info = this.info; this.doUpdateCls(info && !info.valid, invalidCls, oldInvalidCls); }, updateValidCls: function(validCls, oldValidCls) { var info = this.info; this.doUpdateCls(info && info.valid, validCls, oldValidCls); }, destroy: function() { Ext.drag.Manager.unregister(this); this.callParent(); }, privates: { doUpdateCls: function(needsAdd, cls, oldCls) { var el = this.getElement(); if (oldCls) { el.removeCls(oldCls); } if (cls && needsAdd) { el.addCls(cls); } }, getElListeners: function() { return { dragenter: 'handleNativeDragEnter', dragleave: 'handleNativeDragLeave', dragover: 'handleNativeDragMove', drop: 'handleNativeDrop' }; }, handleDrop: function(info) { var me = this, hasListeners = me.hasListeners, valid = info.valid; me.getElement().removeCls([ me.getInvalidCls(), me.getValidCls() ]); if (valid && me.beforeDrop(info) !== false) { if (hasListeners.beforedrop && me.fireEvent('beforedrop', me, info) === false) { return false; } me.onDrop(info); if (hasListeners.drop) { me.fireEvent('drop', me, info); } } else { return false; } }, handleDragEnter: function(info) { var me = this, cls = info.valid ? me.getValidCls() : me.getInvalidCls(); if (cls) { me.getElement().addCls(cls); } me.onDragEnter(info); if (me.hasListeners.dragenter) { me.fireEvent('dragenter', me, info); } }, handleDragLeave: function(info) { var me = this; me.getElement().removeCls([ me.getInvalidCls(), me.getValidCls() ]); me.onDragLeave(info); if (me.hasListeners.dragleave) { me.fireEvent('dragleave', me, info); } }, handleDragMove: function(info) { var me = this; me.onDragMove(info); if (me.hasListeners.dragmove) { me.fireEvent('dragmove', me, info); } }, handleNativeDragEnter: function(e) { var me = this, info = Ext.drag.Manager.getNativeDragInfo(e); info.onNativeDragEnter(me, e); if (me.hasListeners.dragenter) { me.fireEvent('dragenter', me, info); } }, handleNativeDragLeave: function(e) { var me = this, info = Ext.drag.Manager.getNativeDragInfo(e); info.onNativeDragLeave(me, e); if (me.hasListeners.dragleave) { me.fireEvent('dragleave', me, info); } }, handleNativeDragMove: function(e) { var me = this, info = Ext.drag.Manager.getNativeDragInfo(e); info.onNativeDragMove(me, e); if (me.hasListeners.dragmove) { me.fireEvent('dragmove', me, info); } }, handleNativeDrop: function(e) { var me = this, hasListeners = me.hasListeners, info = Ext.drag.Manager.getNativeDragInfo(e), valid = info.valid; info.onNativeDrop(me, e); if (valid) { if (hasListeners.beforedrop && me.fireEvent('beforedrop', me, info) === false) { return; } if (hasListeners.drop) { me.fireEvent('drop', me, info); } } } } }); Ext.define('Ext.drag.proxy.None', { mixins: [ Ext.mixin.Factoryable ], alias: 'drag.proxy.none', factoryConfig: { aliasPrefix: 'drag.proxy.', type: 'dragproxy' }, config: { source: null }, constructor: function(config) { var getElement = config && config.getElement; if (getElement) { this.getElement = getElement; config = Ext.apply({}, config); delete config.getElement; } this.initConfig(config); }, cleanup: Ext.emptyFn, dragRevert: function(info, revertCls, options, callback) { var positionable = this.getPositionable(info), initial = info.proxy.initial; positionable.addCls(revertCls); positionable.setXY([ initial.x, initial.y ], Ext.apply({ callback: function() { positionable.removeCls(revertCls); callback(); } }, options)); }, getElement: function() { return null; }, getPositionable: function() { return this.element; }, setXY: function(info, xy, animation) { var positionable = this.getPositionable(info); if (positionable) { positionable.setXY(xy, animation); } }, update: Ext.emptyFn, privates: { setupElement: function(info) { return (this.element = this.getElement(info)); }, adjustCursorOffset: function(info, pos) { return pos; } } }); Ext.define('Ext.drag.proxy.Original', { extend: Ext.drag.proxy.None, alias: 'drag.proxy.original', getElement: function(info) { return info.source.getElement(); }, getPositionable: function(info) { var source = info.source; return source.getComponent() || source.getElement(); } }); Ext.define('Ext.drag.proxy.Placeholder', { extend: Ext.drag.proxy.None, alias: 'drag.proxy.placeholder', config: { cls: '', cursorOffset: [ 12, 20 ], html: null, invalidCls: '', validCls: '' }, placeholderCls: Ext.baseCSSPrefix + 'drag-proxy-placeholder', cleanup: function() { this.element = Ext.destroy(this.element); }, getElement: function() { var el = Ext.getBody().createChild({ cls: this.getCls(), html: this.getHtml() }); el.addCls(this.placeholderCls); el.setTouchAction({ panX: false, panY: false }); return el; }, update: function(info) { var el = this.element, invalidCls = this.getInvalidCls(), validCls = this.getValidCls(), valid = info.valid; if (info.target) { el.replaceCls(valid ? invalidCls : validCls, valid ? validCls : invalidCls); } else { el.removeCls([ invalidCls, validCls ]); } }, updateCls: function(cls, oldCls) { var el = this.element; if (el) { if (oldCls) { el.removeCls(oldCls); } if (cls) { el.addCls(cls); } } }, updateHtml: function(html) { var el = this.element; if (el) { el.setHtml(html || ''); } }, updateInvalidCls: function(invalidCls, oldInvalidCls) { this.doUpdateCls(invalidCls, oldInvalidCls); }, updateValidCls: function(validCls, oldValidCls) { this.doUpdateCls(validCls, oldValidCls); }, destroy: function() { this.element = Ext.destroy(this.element); this.callParent(); }, privates: { adjustCursorOffset: function(info, xy) { var offset = this.getCursorOffset(); if (offset) { xy[0] += (offset[0] || 0); xy[1] += (offset[1] || 0); } return xy; }, doUpdateCls: function(cls, oldCls) { var el = this.element, hasCls; if (el) { if (oldCls) { hasCls = cls && el.hasCls(oldCls); el.removeCls(oldCls); } if (cls && hasCls) { el.addCls(cls); } } } } }); Ext.define('Ext.event.gesture.Recognizer', { mixins: [ Ext.mixin.Identifiable ], priority: 0, handledEvents: [], isStarted: false, 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: function() { return this.reset(); }, onTouchCancel: function(e) { return this.cancel(e); }, fire: function(eventName, e, info, isCancel) { this.getOnRecognized().call(this.getCallbackScope(), this, eventName, e, info, isCancel); }, cancel: function(e) { if (this.isStarted) { this.onCancel(e); } return this.reset(); }, onCancel: Ext.emptyFn, reset: function() { this.isStarted = false; return false; } }); Ext.define('Ext.event.gesture.SingleTouch', { extend: Ext.event.gesture.Recognizer, isSingleTouch: true, onTouchStart: function(e) { if (e.touches.length > 1) { return this.cancel(e); } } }); Ext.define('Ext.event.gesture.DoubleTap', { extend: Ext.event.gesture.SingleTouch, priority: 300, config: { moveDistance: 8, tapDistance: 24, maxDuration: 300 }, handledEvents: [ 'singletap', 'doubletap' ], singleTapTimer: null, startTime: 0, lastTapTime: 0, onTouchStart: function(e) { var me = this, ret = me.callParent([ e ]), lastStartPoint; if (ret !== false) { me.isStarted = true; lastStartPoint = me.lastStartPoint = e.changedTouches[0].point; me.startPoint = me.startPoint || lastStartPoint; me.startTime = e.time; Ext.undefer(me.singleTapTimer); } return ret; }, onTouchMove: function(e) { var me = this, point = e.changedTouches[0].point, scale = Ext.Element.getViewportScale(), distance = Math.round(Math.abs(point.getDistanceTo(me.lastStartPoint) * scale)); if (distance >= me.getMoveDistance()) { return me.cancel(e); } }, 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, scale, distance; me.lastTapTime = time; me.lastTarget = target; if (lastTapTime) { duration = time - lastTapTime; if (duration <= maxDuration) { scale = Ext.Element.getViewportScale(); distance = Math.round(Math.abs(point.getDistanceTo(me.startPoint) * scale)); if (distance <= me.getTapDistance()) { if (target !== lastTarget) { return me.cancel(e); } me.lastTarget = null; me.lastTapTime = 0; me.fire('doubletap', e, { touch: e.changedTouches[0], duration: duration }); return me.callParent([ e ]); } } } if (time - me.startTime > maxDuration) { me.fire('singletap', e); me.reset(); } else { me.setSingleTapTimer(e); } }, setSingleTapTimer: function(e) { var me = this; me.singleTapTimer = Ext.defer(function() { me.fire('singletap', e); me.reset(); }, me.getMaxDuration()); }, reset: function() { var me = this; Ext.undefer(me.singleTapTimer); me.startTime = me.lastTapTime = 0; me.lastStartPoint = me.startPoint = me.singleTapTimer = null; return me.callParent(); } }, 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, 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 }, longpress: false }; }, onTouchStart: function(e) { var me = this, ret = me.callParent([ e ]); if (ret !== false) { me.startTime = e.time; me.startPoint = e.changedTouches[0].point; } return ret; }, tryDragStart: function(e) { var me = this, point = e.changedTouches[0].point, minDistance = me.getMinDistance(), scale = Ext.Element.getViewportScale(), distance = Math.round(Math.abs(point.getDistanceTo(me.startPoint) * scale)); if (distance >= minDistance) { me.doDragStart(e); } }, doDragStart: function(e, isLongPress) { var me = this, touch = e.changedTouches[0], point = touch.point, info = me.info, time; if (isLongPress) { time = Ext.now(); me.startTime = time; me.startPoint = point; info.longpress = true; } else { time = e.time; } me.isStarted = true; me.previousPoint = me.lastPoint = point; me.resetInfo('x', e, touch); me.resetInfo('y', e, touch); info.time = time; me.fire('dragstart', e, info); }, onTouchMove: function(e) { var me = this, touch, point; if (!me.startPoint) { return; } if (!me.isStarted) { me.tryDragStart(e); } if (!me.isStarted) { return; } touch = e.changedTouches[0]; point = touch.point; if (me.lastPoint) { me.previousPoint = me.lastPoint; } me.lastPoint = point; me.lastMoveEvent = e; me.updateInfo('x', e, touch); me.updateInfo('y', e, touch); me.info.time = e.time; me.fire('drag', e, me.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 me = this, value = me.lastPoint[axis], startValue = me.startPoint[axis], delta = value - startValue, capAxis = axis.toUpperCase(), info = me.info; info.touch = touch; info.delta[axis] = delta; info.absDelta[axis] = Math.abs(delta); info.previousTime[axis] = me.startTime; info.previous[axis] = startValue; info[axis] = value; info.direction[axis] = 0; info['start' + capAxis] = me.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 = me.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) { var me = this, touch, point, info; if (me.isStarted) { touch = e.changedTouches[0]; point = touch.point; info = me.info; me.lastPoint = point; me.updateInfo('x', e, touch); me.updateInfo('y', e, touch); info.time = e.time; me.onAxisDragEnd('x', info); me.onAxisDragEnd('y', info); me.fire('dragend', e, info); } return this.callParent([ e ]); }, onCancel: function(e) { var me = this, touch = e.changedTouches[0], info = me.info; if (!e.touches.length) { me.lastPoint = touch.point; } me.updateInfo('x', e, touch); me.updateInfo('y', e, touch); info.time = e.time; me.fire('dragcancel', e, info, true); }, reset: function() { var me = this; me.lastPoint = me.startPoint = me.previousPoint = me.lastPoint = me.lastMoveEvent = null; me.initInfo(); return me.callParent(); } }, 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: 600, handledEvents: [ 'swipestart', 'swipe', 'swipecancel' ], config: { minDistance: 80, maxOffset: 35, maxDuration: 1000 }, onTouchStart: function(e) { var me = this, ret = me.callParent([ e ]), touch; if (ret !== false) { touch = e.changedTouches[0]; me.startTime = e.time; me.isHorizontal = true; me.isVertical = true; me.startX = touch.pageX; me.startY = touch.pageY; } return ret; }, onTouchMove: function(e) { var me = this, touch = e.changedTouches[0], x = touch.pageX, y = touch.pageY, deltaX = x - me.startX, deltaY = y - me.startY, absDeltaX = Math.abs(x - me.startX), absDeltaY = Math.abs(y - me.startY), duration = e.time - me.startTime, minDistance, direction, distance; if ((absDeltaX === 0 && absDeltaY === 0) || (duration > me.getMaxDuration())) { return me.cancel(e); } if (me.isHorizontal && absDeltaY > me.getMaxOffset()) { me.isHorizontal = false; } if (me.isVertical && absDeltaX > me.getMaxOffset()) { me.isVertical = false; } if (!me.isVertical || !me.isHorizontal) { minDistance = me.getMinDistance(); if (me.isHorizontal && absDeltaX < minDistance) { direction = (deltaX < 0) ? 'left' : 'right'; distance = absDeltaX; } else if (me.isVertical && absDeltaY < minDistance) { direction = (deltaY < 0) ? 'up' : 'down'; distance = absDeltaY; } } if (!me.isHorizontal && !me.isVertical) { return me.cancel(e); } if (direction && !me.isStarted) { me.isStarted = true; me.fire('swipestart', e, { touch: touch, direction: direction, distance: distance, duration: duration }); } }, onTouchEnd: function(e) { var me = this, touch, x, y, deltaX, deltaY, absDeltaX, absDeltaY, minDistance, duration, direction, distance; if (me.onTouchMove(e) !== false) { touch = e.changedTouches[0]; x = touch.pageX; y = touch.pageY; deltaX = x - me.startX; deltaY = y - me.startY; absDeltaX = Math.abs(deltaX); absDeltaY = Math.abs(deltaY); minDistance = me.getMinDistance(); duration = e.time - me.startTime; if (me.isVertical && absDeltaY < minDistance) { me.isVertical = false; } if (me.isHorizontal && absDeltaX < minDistance) { me.isHorizontal = false; } if (me.isHorizontal) { direction = (deltaX < 0) ? 'left' : 'right'; distance = absDeltaX; } else if (me.isVertical) { direction = (deltaY < 0) ? 'up' : 'down'; distance = absDeltaY; } me.fire('swipe', e, { touch: touch, direction: direction, distance: distance, duration: duration }); } return this.callParent([ e ]); }, onCancel: function(e) { this.fire('swipecancel', e, null, true); }, reset: function() { var me = this; me.startTime = me.isHorizontal = me.isVertical = me.startX = me.startY = null; return me.callParent(); } }, 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: 500, handledEvents: [ 'edgeswipe', 'edgeswipestart', 'edgeswipeend', 'edgeswipecancel' ], config: { minDistance: 60 }, onTouchStart: function(e) { var me = this, ret = me.callParent([ e ]), touch; if (ret !== false) { touch = e.changedTouches[0]; me.direction = null; me.isHorizontal = true; me.isVertical = true; me.startX = touch.pageX; me.startY = touch.pageY; } return ret; }, onTouchMove: function(e) { var me = this, touch = e.changedTouches[0], x = touch.pageX, y = touch.pageY, deltaX = x - me.startX, deltaY = y - me.startY, absDeltaY = Math.abs(y - me.startY), absDeltaX = Math.abs(x - me.startX), minDistance = me.getMinDistance(), maxOffset = me.getMaxOffset(), duration = e.time - me.startTime, elementWidth = Ext.Viewport && Ext.Element.getViewportWidth(), elementHeight = Ext.Viewport && Ext.Element.getViewportHeight(), direction, distance; if (me.isVertical && absDeltaX > maxOffset) { me.isVertical = false; } if (me.isHorizontal && absDeltaY > maxOffset) { me.isHorizontal = false; } if (me.isVertical && me.isHorizontal) { if (absDeltaY > absDeltaX) { me.isHorizontal = false; } else { me.isVertical = false; } } if (me.isHorizontal) { direction = (deltaX < 0) ? 'left' : 'right'; distance = deltaX; } else if (me.isVertical) { direction = (deltaY < 0) ? 'up' : 'down'; distance = deltaY; } direction = me.direction || (me.direction = direction); if (direction === 'up') { distance = deltaY * -1; } else if (direction === 'left') { distance = deltaX * -1; } me.distance = distance; if (!distance) { return me.cancel(e); } if (!me.isStarted) { if ((direction === 'right' && me.startX > minDistance) || (direction === 'down' && me.startY > minDistance) || (direction === 'left' && (elementWidth - me.startX) > minDistance) || (direction === 'up' && (elementHeight - me.startY) > minDistance)) { return me.cancel(e); } me.isStarted = true; me.startTime = e.time; me.fire('edgeswipestart', e, { touch: touch, direction: direction, distance: distance, duration: duration }); } else { me.fire('edgeswipe', e, { touch: touch, direction: direction, distance: distance, duration: duration }); } }, onTouchEnd: function(e) { var me = this, duration; if (me.onTouchMove(e) !== false) { duration = e.time - me.startTime; me.fire('edgeswipeend', e, { touch: e.changedTouches[0], direction: me.direction, distance: me.distance, duration: duration }); } return this.reset(); }, onCancel: function(e) { this.fire('edgeswipecancel', e, { touch: e.changedTouches[0] }, true); }, reset: function() { var me = this; me.direction = me.isHorizontal = me.isVertical = me.startX = me.startY = me.startTime = me.distance = null; return me.callParent(); } }, 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, config: { moveDistance: 8, minDuration: 1000 }, handledEvents: [ 'longpress', 'taphold' ], onTouchStart: function(e) { var me = this, ret = me.callParent([ e ]); if (ret !== false) { me.startPoint = e.changedTouches[0].point; me.setLongPressTimer(e); } return ret; }, setLongPressTimer: function(e) { var me = this; Ext.undefer(me.timer); me.timer = Ext.defer(me.fireLongPress, me.getMinDuration(), me, [ e ]); }, onTouchMove: function(e) { var me = this, point = e.changedTouches[0].point, scale = Ext.Element.getViewportScale(), distance = Math.round(Math.abs(point.getDistanceTo(me.startPoint) * scale)); if (distance >= me.getMoveDistance()) { return me.cancel(e); } }, reset: function() { var me = this; me.timer = me.startPoint = Ext.undefer(me.timer); return me.callParent(); }, fireLongPress: function(e) { var me = this, info = { touch: e.changedTouches[0], duration: me.getMinDuration(), startDrag: me.startDrag }; this.fire('taphold', e, info); this.fire('longpress', e, info); this.reset(); }, startDrag: function() { var dragRecognizer = Ext.event.gesture.Drag.instance, touchStartEvent = this.parentEvent; dragRecognizer.doDragStart(touchStartEvent, true); Ext.event.publisher.Gesture.instance.claimRecognizer(dragRecognizer, touchStartEvent); } }, 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, isMultiTouch: true, onTouchStart: function(e) { var me = this, requiredTouchesCount = me.requiredTouchesCount, touches = e.touches, touchesCount = touches.length; if (touchesCount === requiredTouchesCount) { me.isTracking = true; } else if (touchesCount > requiredTouchesCount) { return me.cancel(e); } }, reset: function() { this.isTracking = false; return this.callParent(); } }); Ext.define('Ext.event.gesture.Pinch', { extend: Ext.event.gesture.MultiTouch, priority: 700, handledEvents: [ 'pinchstart', 'pinch', 'pinchend', 'pinchcancel' ], startDistance: 0, lastTouches: null, onTouchMove: function(e) { var me = this, touches, firstPoint, secondPoint, distance; if (me.isTracking) { touches = e.touches; firstPoint = touches[0].point; secondPoint = touches[1].point; distance = firstPoint.getDistanceTo(secondPoint); if (distance === 0) { return; } if (!me.isStarted) { me.isStarted = true; me.startDistance = distance; me.fire('pinchstart', e, { touches: touches, distance: distance, scale: 1 }); } else { me.fire('pinch', e, { touches: touches, distance: distance, scale: distance / me.startDistance }); } } }, onTouchEnd: function(e) { if (this.isStarted) { this.fire('pinchend', e); } return this.callParent([ e ]); }, onCancel: function(e) { this.fire('pinchcancel', e, null, true); }, reset: function() { this.lastTouches = null; this.startDistance = 0; return 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: 800, handledEvents: [ 'rotatestart', 'rotate', 'rotateend', 'rotatecancel' ], startAngle: 0, lastTouches: null, lastAngle: null, onTouchMove: function(e) { var me = this, touches, lastAngle, firstPoint, secondPoint, angle, nextAngle, previousAngle, diff; if (me.isTracking) { touches = e.touches; lastAngle = me.lastAngle; 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; } } me.lastAngle = angle; if (!me.isStarted) { me.isStarted = true; me.startAngle = angle; me.fire('rotatestart', e, { touches: touches, angle: angle, rotation: 0 }); } else { me.fire('rotate', e, { touches: touches, angle: angle, rotation: angle - me.startAngle }); } me.lastTouches = Ext.Array.clone(touches); } }, onTouchEnd: function(e) { if (this.isStarted) { this.fire('rotateend', e); } return this.callParent([ e ]); }, onCancel: function(e) { this.fire('rotatecancel', e, null, true); }, reset: function() { var me = this; me.lastTouches = me.lastAngle = me.startAngle = null; return 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) { var me = this, ret = me.callParent([ e ]); if (ret !== false) { me.isStarted = true; me.startPoint = e.changedTouches[0].point; } return ret; }, onTouchMove: function(e) { var me = this, point = e.changedTouches[0].point, scale = Ext.Element.getViewportScale(), distance = Math.round(Math.abs(point.getDistanceTo(me.startPoint) * scale)); if (distance >= me.getMoveDistance()) { return me.cancel(e); } }, onTouchEnd: function(e) { this.fire('tap', e, { touch: e.changedTouches[0] }); return this.callParent([ e ]); }, onCancel: function(e) { this.fire('tapcancel', e, { touch: e.changedTouches[0] }, true); }, reset: function() { this.startPoint = null; return this.callParent(); } }, function(Tap) { var gestures = Ext.manifest.gestures; Tap.instance = new Tap(gestures && gestures.tap); }); Ext.define('Ext.event.publisher.Focus', { extend: Ext.event.publisher.Dom, type: 'focus', handledEvents: [ 'focusenter', 'focusleave', 'focusmove' ], handledDomEvents: [ 'focusin', 'focusout' ], publishDelegatedDomEvent: function(e) { var me = this, relatedTarget = e.relatedTarget; if (me.$suppressEvents) { return; } if (e.type === 'focusout') { if (relatedTarget == null) { me.processFocusIn(e, e.target, document.body); } } else { if (relatedTarget == null || !relatedTarget.tagName) { relatedTarget = document.body; } me.processFocusIn(e, relatedTarget, e.target); } }, processFocusIn: function(e, fromElement, toElement) { var me = this, commonAncestor, node, targets = [], focusFly = me.focusFly, backwards, event, focusEnterEvent; if ((fromElement && focusFly.attach(fromElement).isFocusSuspended()) || (toElement && focusFly.attach(toElement).isFocusSuspended())) { return; } if (toElement.compareDocumentPosition) { backwards = !!(toElement.compareDocumentPosition(fromElement) & 4); } for (node = fromElement , commonAncestor = Ext.dom.Element.getCommonAncestor(toElement, fromElement, true); node && node !== commonAncestor; node = node.parentNode) { targets.push(node); } if (targets.length) { event = me.createSyntheticEvent('focusleave', e, fromElement, toElement, fromElement, toElement, backwards); me.publish(event, targets); if (event.stopped) { return; } } targets.length = 0; for (node = toElement; node && node !== commonAncestor; node = node.parentNode) { targets.push(node); } focusEnterEvent = me.createSyntheticEvent('focusenter', e, toElement, fromElement, fromElement, toElement, backwards); if (targets.length) { me.publish(focusEnterEvent, targets); if (focusEnterEvent.stopped) { return; } } targets = me.getPropagatingTargets(commonAncestor); if (targets.length) { event = me.createSyntheticEvent('focusmove', e, toElement, fromElement, fromElement, toElement, backwards); me.publish(event, targets); if (event.stopped) { return; } } if (Ext.GlobalEvents.hasListeners.focus) { Ext.GlobalEvents.fireEvent('focus', { event: focusEnterEvent, toElement: toElement, fromElement: fromElement, backwards: backwards }); } }, createSyntheticEvent: function(eventName, browserEvent, target, relatedTarget, fromElement, toElement, backwards) { var event = new Ext.event.Event(browserEvent); event.type = eventName; event.relatedTarget = relatedTarget; event.target = target; event.fromElement = fromElement; event.toElement = toElement; event.backwards = backwards; return event; } }, function(Focus) { var focusTimeout; Focus.prototype.focusFly = new Ext.dom.Fly(); Focus.instance = new Focus(); if (!Ext.supports.FocusinFocusoutEvents) { this.override({ handledDomEvents: [ 'focus', 'blur' ], publishDelegatedDomEvent: function(e) { var me = this, targetIsElement; me.callSuper([ e ]); targetIsElement = e.target !== window && e.target !== document; if (e.type === 'blur') { if (!targetIsElement) { if (e.explicitOriginalTarget === Focus.previousActiveElement) { if (e.target === window) { Ext.undefer(focusTimeout); focusTimeout = 0; me.processFocusIn(e, Focus.previousActiveElement, document.body); Focus.previousActiveElement = null; } } } else { focusTimeout = Ext.defer(function() { focusTimeout = 0; me.processFocusIn(e, e.target, document.body); Focus.previousActiveElement = null; }, 1); if (targetIsElement && Ext.cache[e.target.id]) { Ext.cache[e.target.id].focusinTimeout = focusTimeout; } } Focus.previousActiveElement = targetIsElement ? e.target : null; } else { Ext.undefer(focusTimeout); focusTimeout = 0; me.processFocusIn(e, Focus.previousActiveElement || document.body, targetIsElement ? e.target : document.body); } } }); Ext.define(null, { override: 'Ext.dom.Element', destroy: function() { if (this.focusinTimeout) { Ext.undefer(this.focusinTimeout); this.focusinTimeout = null; } this.callParent(); } }); } }); Ext.define('Ext.field.InputMask', function(InputMask) { return { cachedConfig: { blank: '_', characters: { '*': '[A-Za-z0-9]', 'a': '[a-z]', 'A': '[A-Z]', '0': '[0-9]', '9': '[0-9]' }, ignoreCase: true }, config: { pattern: null }, _cached: false, _lastEditablePos: null, _mask: null, statics: { active: {}, from: function(value, existing) { var active = InputMask.active, ret; if (value === null) { ret = null; } else if (typeof value !== 'string') { if (existing && !existing._cached) { ret = existing; ret.setConfig(value); } else { ret = new InputMask(value); } } else if (!(ret = active[value])) { if (!(ret = InputMask.cache.remove(value))) { ret = new InputMask({ pattern: value }); } active[value] = ret; ret._cached = 1; } else { ++ret._cached; } return ret; } }, constructor: function(config) { this.initConfig(config); }, release: function() { var me = this, cache = InputMask.cache, key; if (me._cached && !--me._cached) { key = me.getPattern(); if (InputMask.active[key] !== me) { Ext.raise('Invalid call to InputMask#release (not active)'); } if (cache.map[key]) { Ext.raise('Invalid call to InputMask#release (already cached)'); } delete InputMask.active[key]; cache.add(key, me); cache.trim(cache.maxSize); } else if (me._cached === 0) { Ext.raise('Invalid call to InputMask#release (already released)'); } }, clearRange: function(value, start, len) { var me = this, blank = me.getBlank(), end = start + len, n = value.length, s = '', i, mask, prefixLen; if (!blank) { prefixLen = me._prefix.length; for (i = 0; i < n; ++i) { if (i < prefixLen || i < start || i >= end) { s += value[i]; } } s = me.formatValue(s); } else { mask = me.getPattern(); for (i = 0; i < n; ++i) { if (i < start || i >= end) { s += value[i]; } else if (me.isFixedChar(i)) { s += mask[i]; } else { s += blank; } } } return s; }, formatValue: function(value) { var me = this, blank = me.getBlank(), i, length, mask, prefix, s; if (!blank) { prefix = me._prefix; length = prefix.length; s = this.insertRange('', value, 0); for (i = s.length; i > length && me.isFixedChar(i - 1); ) { --i; } s = (i < length) ? prefix : s.slice(0, i - 1); } else if (value) { s = me.formatValue(''); s = me.insertRange(s, value, 0); } else { mask = me.getPattern(); s = ''; for (i = 0 , length = mask.length; i < length; ++i) { if (me.isFixedChar(i)) { s += mask[i]; } else { s += blank; } } } return s; }, getEditPosLeft: function(pos) { for (var i = pos; i >= 0; --i) { if (!this.isFixedChar(i)) { return i; } } return null; }, getEditPosRight: function(pos) { var mask = this._mask, len = mask.length, i; for (i = pos; i < len; ++i) { if (!this.isFixedChar(i)) { return i; } } return null; }, getFilledLength: function(value) { var me = this, blank = me.getBlank(), c, i; if (!blank) { return value.length; } for (i = value && value.length; i-- > 0; ) { c = value[i]; if (!me.isFixedChar(i) && me.isAllowedChar(c, i)) { break; } } return ++i || me._prefix.length; }, getSubLength: function(value, substr, pos) { var me = this, mask = me.getPattern(), k = 0, maskLen = mask.length, substrLen = substr.length, i; for (i = pos; i < maskLen && k < substrLen; ) { if (!me.isFixedChar(i) || mask[i] === substr[k]) { if (me.isAllowedChar(substr[k++], i, true)) { ++i; } } else { ++i; } } return i - pos; }, insertRange: function(value, substr, pos) { var me = this, mask = me.getPattern(), blank = me.getBlank(), filled = me.isFilled(value), prefixLen = me._prefix.length, maskLen = mask.length, substrLen = substr.length, s = value, ch, fixed, i, k; if (!blank && pos > s.length) { s += mask.slice(s.length, pos); } for (i = pos , k = 0; i < maskLen && k < substrLen; ) { fixed = me.isFixedChar(i); if (!fixed || mask[i] === substr[k]) { ch = substr[k++]; if (me.isAllowedChar(ch, i, true)) { if (i < s.length) { if (blank || filled || i < prefixLen) { s = s.slice(0, i) + ch + s.slice(i + 1); } else { s = me.formatValue(s.substr(0, i) + ch + s.substr(i)); } } else if (!blank) { s += ch; } ++i; } } else { if (!blank && i >= s.length) { s += mask[i]; } else if (blank && fixed && substr[k] === blank) { ++k; } ++i; } } return s; }, isAllowedChar: function(character, pos, allowBlankChar) { var me = this, mask = me.getPattern(), c, characters, rule; if (me.isFixedChar(pos)) { return mask[pos] === character; } c = mask[pos]; characters = me.getCharacters(); rule = characters[c]; return !rule || rule.test(character || '') || (allowBlankChar && character === me.getBlank()); }, isEmpty: function(value) { for (var i = 0, len = value.length; i < len; ++i) { if (!this.isFixedChar(i) && this.isAllowedChar(value[i], i)) { return false; } } return true; }, isFilled: function(value) { return this.getFilledLength(value) === this._mask.length; }, isFixedChar: function(pos) { return Ext.Array.indexOf(this._fixedCharPositions, pos) > -1; }, setCaretToEnd: function(field, value) { var filledLen = this.getFilledLength(value), pos = this.getEditPosRight(filledLen); if (pos !== null) { Ext.raf(function() { if (!field.destroyed) { field.setCaretPos(pos); Ext.raf(function() { if (!field.destroyed) { field.setCaretPos(pos); } }); } }); } }, onBlur: function(field, value) { if (field.getAutoHideInputMask() !== false) { if (this.isEmpty(value)) { field.maskProcessed = true; field.setValue(''); } } }, onFocus: function(field, value) { if (field.getAutoHideInputMask() !== false) { if (!value) { field.maskProcessed = true; field.setValue(this._mask); } } this.setCaretToEnd(field, value); }, onChange: function(field, value, oldValue) { var me = this, s; if (field.maskProcessed || value === oldValue) { field.maskProcessed = false; return true; } if (value) { s = me.formatValue(value); field.maskProcessed = true; field.setValue(s); } }, processAutocomplete: function(field, value) { var me = this, s; if (value) { if (value.length > me._mask.length) { value = value.substr(0, me._mask.length); } s = me.formatValue(value); field.maskProcessed = true; field.inputElement.dom.value = s; field.setValue(s); this.setCaretToEnd(field, value); } }, showEmptyMask: function(field, adjustCaret) { var s = this.formatValue(); field.maskProcessed = true; field.setValue(s); if (adjustCaret) { this.setCaretToEnd(field); } }, onKeyDown: function(field, value, event) { if (event.ctrlKey || event.metaKey) { return; } var me = this, key = event.keyCode === event.DELETE, del = key === 'Delete', handled = del || (event.keyCode === event.BACKSPACE), s = value, caret, editPos, len, prefixLen, textSelection, start; if (handled) { caret = field.getCaretPos(); prefixLen = me._prefix.length; textSelection = field.getTextSelection(); start = textSelection[0]; len = textSelection[1] - start; if (len) { s = me.clearRange(value, start, len); } else if (caret < prefixLen || (!del && caret === prefixLen)) { caret = prefixLen; } else { editPos = del ? me.getEditPosRight(caret) : me.getEditPosLeft(caret - 1); if (editPos !== null) { s = me.clearRange(value, editPos, 1); caret = editPos; } } if (s !== value) { field.maskProcessed = true; field.setValue(s); } event.preventDefault(); field.setCaretPos(caret); } }, onKeyPress: function(field, value, event) { var me = this, key = event.keyCode, ch = event.getChar(), mask = me.getPattern(), prefixLen = me._prefix.length, s = value, caretPos, pos, start, textSelection; if (key === event.ENTER || key === event.TAB || event.ctrlKey || event.metaKey) { return; } caretPos = field.getCaretPos(); textSelection = field.getTextSelection(); if (me.isFixedChar(caretPos) && mask[caretPos] === ch) { s = me.insertRange(s, ch, caretPos); ++caretPos; } else { pos = me.getEditPosRight(caretPos); if (pos !== null && me.isAllowedChar(ch, pos)) { start = textSelection[0]; s = me.clearRange(s, start, textSelection[1] - start); s = me.insertRange(s, ch, pos); caretPos = pos + 1; } } if (s !== value) { field.maskProcessed = true; field.setValue(s); } event.preventDefault(); if (caretPos < me._lastEditablePos && caretPos > prefixLen) { caretPos = me.getEditPosRight(caretPos); } field.setCaretPos(caretPos); }, onPaste: function(field, value, event) { var text, clipdData = event.browserEvent.clipboardData; if (clipdData && clipdData.getData) { text = clipdData.getData('text/plain'); } else if (Ext.global.clipboardData && Ext.global.clipboardData.getData) { text = Ext.global.clipboardData.getData('Text'); } if (text) { this.paste(field, value, text, field.getTextSelection()); } event.preventDefault(); }, paste: function(field, value, text, selection) { var me = this, caretPos = selection[0], len = selection[1] - caretPos, s = len ? me.clearRange(value, caretPos, len) : value, textLen = me.getSubLength(s, text, caretPos); s = me.insertRange(s, text, caretPos); caretPos += textLen; caretPos = me.getEditPosRight(caretPos) || caretPos; if (s !== value) { field.maskProcessed = true; field.setValue(s); } field.setCaretPos(caretPos); }, syncPattern: function(field) { var fieldValue = field.getValue(), s; if (field.getAutoHideInputMask() === false) { if (!fieldValue) { this.showEmptyMask(field); } else { s = this.formatValue(fieldValue); field.maskProcessed = true; field.setValue(s); } } else { if (fieldValue) { s = this.formatValue(fieldValue); field.maskProcessed = true; field.setValue(s); } } }, applyCharacters: function(map) { var ret = {}, flags = this.getIgnoreCase() ? 'i' : '', c, v; for (c in map) { v = map[c]; if (typeof v === 'string') { v = new RegExp(v, flags); } ret[c] = v; } return ret; }, updatePattern: function(mask) { var me = this, characters = me.getCharacters(), lastEditablePos = 0, n = mask && mask.length, blank = me.getBlank(), fixedPosArr = [], prefix = '', str = '', c, i; for (i = 0; i < n; ++i) { c = mask[i]; if (!characters[c]) { fixedPosArr.push(str.length); str += c; } else { lastEditablePos = str.length + 1; str += blank; } } me._lastEditablePos = lastEditablePos; me._mask = str; me._fixedCharPositions = fixedPosArr; for (i = 0; i < str.length && me.isFixedChar(i); ++i) { prefix += str[i]; } me._prefix = prefix; } }; }, function(InputMask) { InputMask.cache = new Ext.util.LRU(); InputMask.cache.maxSize = 100; }); Ext.define('Ext.fx.runner.Css', { extend: Ext.Evented, 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, 'x': true, 'y': 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 }, DEFAULT_UNIT_LENGTH: 'px', DEFAULT_UNIT_ANGLE: 'deg', DEFAULT_UNIT_DURATION: 'ms', customProperties: { x: true, y: true }, formattedNameCache: { 'x': 'left', 'y': 'top' }, transformMethods3d: [ 'translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'skewX', 'skewY', 'scaleX', 'scaleY', 'scaleZ' ], transformMethodsNo3d: [ 'translateX', 'translateY', 'rotate', 'skewX', 'skewY', 'scaleX', 'scaleY' ], constructor: function() { var me = this; me.transformMethods = Ext.feature.has.Css3dTransforms ? me.transformMethods3d : me.transformMethodsNo3d; me.vendorPrefix = Ext.browser.getStyleDashPrefix(); me.ruleStylesCache = {}; me.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); } } } } return this; }, applyStyles: function(styles) { var id, element, elementStyle, properties, name, value; for (id in styles) { if (styles.hasOwnProperty(id)) { this.activeElement = element = document.getElementById(id); if (!element) { continue; } 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); } } } } } this.activeElement = null; 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, defaultLengthUnit = this.DEFAULT_UNIT_LENGTH, isCustom = this.customProperties[name], transformMethods, method, i, ln, transformValues, values; if (value === null) { return ''; } if (type === 'string') { if (this.lengthProperties[name]) { if (!Ext.dom.Element.hasUnit(value)) { value = value + defaultLengthUnit; if (isCustom) { value = this.getCustomValue(value, name); } } } return value; } else if (type === 'number') { if (value === 0) { return '0'; } if (this.lengthProperties[name]) { value = value + defaultLengthUnit; if (isCustom) { value = this.getCustomValue(value, name); } return value; } 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; }, getCustomValue: function(value, name) { var el = Ext.fly(this.activeElement); if (name === 'x') { value = el.translateXY(parseInt(value, 10)).x; } else if (name === 'y') { value = el.translateXY(null, parseInt(value, 10)).y; } return value + this.DEFAULT_UNIT_LENGTH; } }); Ext.define('Ext.fx.runner.CssTransition', { extend: Ext.fx.runner.Css, alternateClassName: 'Ext.Animator', singleton: true, listenersAttached: false, constructor: function() { this.runningAnimationsData = {}; this.transitionQueue = { toData: {}, transitionData: {} }; 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 ]); } }, getElementId: function(element) { return element.getId ? element.getId() : element.id; }, onAnimationEnd: function(element, data, animation, isInterrupted, isReplaced) { var id = this.getElementId(element), 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 = this.getElementId(element), transitionQueue = this.transitionQueue, endRules = {}; delete this.runningAnimationsData[id]; endRules[id] = { 'transition-property': null, 'transition-duration': null, 'transition-timing-function': null, 'transition-delay': null }; delete transitionQueue.toData[id]; delete transitionQueue.transitionData[id]; this.applyStyles(endRules); this.fireEvent('animationallend', this, element); }, hasRunningAnimations: function(element) { var id = this.getElementId(element), runningAnimationsData = this.runningAnimationsData; return runningAnimationsData.hasOwnProperty(id) && runningAnimationsData[id].sessions.length > 0; }, refreshRunningAnimationsData: function(element, propertyNames, interrupt, replace) { var id = this.getElementId(element), 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 me = this, testElement = me.testElement, iframe = me.iframe, iframeDocument, iframeStyle; if (testElement) { if (testElement.ownerDocument.defaultView !== iframe.contentWindow) { iframeDocument = iframe.contentDocument; iframeDocument.body.appendChild(testElement); me.testElementComputedStyle = iframeDocument.defaultView.getComputedStyle(testElement); } } else { iframe = me.iframe = document.createElement('iframe'); iframe.setAttribute('data-sticky', true); 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(); me.testElement = testElement = iframeDocument.createElement('div'); testElement.style.setProperty('position', 'absolute', 'important'); iframeDocument.body.appendChild(testElement); me.testElementComputedStyle = iframeDocument.defaultView.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, ret = [], isLengthPropertyMap = me.lengthProperties, fromData = {}, toData = me.transitionQueue.toData, data = {}, transitionData = me.transitionQueue.transitionData, 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, messageTimerFn, onBeforeStart; if (!me.listenersAttached) { me.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); ret.push(animation); me.activeElement = element = animation.getElement(); Ext.AnimationQueue.start(Ext.emptyFn, animation); computedStyle = window.getComputedStyle(element.dom); elementId = me.getElementId(element); data[elementId] = data = Ext.merge({}, animation.getData()); onBeforeStart = animation.getOnBeforeStart(); if (onBeforeStart) { onBeforeStart.call(animation.scope || me, element); } animation.fireEvent('animationstart', animation, data); me.fireEvent('animationstart', me, animation, 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 = me.formatValue(to[name], name); formattedName = me.formatName(name); isLengthProperty = isLengthPropertyMap.hasOwnProperty(name); if (!isLengthProperty) { toFormattedValue = me.getCssStyleValue(formattedName, toFormattedValue); } if (from.hasOwnProperty(name)) { from[name] = fromFormattedValue = me.formatValue(from[name], name); if (!isLengthProperty) { fromFormattedValue = me.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) { me.onAnimationEnd(element, data, animation); continue; } runningData = me.getRunningData(elementId); runningSessions = runningData.sessions; if (runningSessions.length > 0) { me.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', me); 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); transitionData[elementId] = { 'transition-property': toPropertyNames, 'transition-duration': data.duration, 'transition-timing-function': data.easing, 'transition-delay': data.delay }; animation.startTime = Date.now(); } me.activeElement = null; message = me.$className; me.applyStyles(fromData); doApplyTo = function(e) { if (e.data === message && e.source === window) { window.removeEventListener('message', doApplyTo, false); me.applyStyles(me.transitionQueue.toData); } }; if (!me.messageTimerId) { messageTimerFn = function() { var messageFollowupFn; me.messageTimerId = null; if (Ext.isIE) { me.applyStyles(me.transitionQueue.transitionData); if (!me.messageFollowupId) { messageFollowupFn = function() { me.messageFollowupId = null; window.addEventListener('message', doApplyTo, false); window.postMessage(message, '*'); }; messageFollowupFn.$skipTimerCheck = true; me.messageFollowupId = Ext.raf(messageFollowupFn); } } else { Ext.merge(me.transitionQueue.toData, me.transitionQueue.transitionData); window.addEventListener('message', doApplyTo, false); window.postMessage(message, '*'); } }; messageTimerFn.$skipTimerCheck = true; me.messageTimerId = Ext.raf(messageTimerFn); } return ret; }, onAnimationStop: function(animation) { var me = this, runningAnimationsData = me.runningAnimationsData, activeAnimations = 0, stoppedAnimations = 0, id, runningData, sessions, i, ln, session; for (id in runningAnimationsData) { if (runningAnimationsData.hasOwnProperty(id)) { runningData = runningAnimationsData[id]; sessions = runningData.sessions; activeAnimations++; for (i = 0 , ln = sessions.length; i < ln; i++) { session = sessions[i]; if (session.animation === animation) { me.refreshRunningAnimationsData(session.element, session.list.slice(), false); if (animation.destroying) { stoppedAnimations++; } } } } } if (activeAnimations === stoppedAnimations) { if (me.messageFollowupId) { Ext.unraf(me.messageFollowupId); me.messageFollowupId = null; } if (me.messageTimerId) { Ext.unraf(me.messageTimerId); me.messageTimerId = null; } Ext.apply(me.transitionQueue, { toData: {}, transitionData: {} }); } } }); Ext.define('Ext.fx.Runner', { 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.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.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.BoundMomentum', { extend: Ext.fx.easing.Abstract, 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.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.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.fx.easing.Easing', { constructor: function(easing) { return Ext.factory(easing, Ext.fx.easing.Linear, null, 'easing'); } }); 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.list.AbstractTreeItem', { extend: Ext.Widget, isTreeListItem: true, cachedConfig: { expandable: false, expanded: false, iconCls: '', leaf: true, loading: false, selected: false, selectedParent: false }, config: { iconClsProperty: 'iconCls', indent: null, owner: null, node: null, over: null, parentItem: null, text: { lazy: true, $value: '' }, textProperty: 'text' }, updateNode: function(node) { if (node) { var me = this, map = me.itemMap, childNodes, owner, len, i, item, child; me.element.dom.setAttribute('data-recordId', node.internalId); if (!map) { childNodes = node.childNodes; owner = me.getOwner(); me.itemMap = map = {}; for (i = 0 , len = childNodes.length; i < len; ++i) { child = childNodes[i]; if (child.data.visible) { item = owner.createItem(child, me); map[child.internalId] = item; me.insertItem(item, null); } } } me.setExpanded(node.isExpanded()); me.doNodeUpdate(node); } }, updateSelected: function(selected) { if (!this.isConfiguring) { var parent = this.getParentItem(); while (parent && !parent.isRootListItem) { parent.setSelectedParent(selected); parent = parent.getParentItem(); } } }, collapse: function() { this.getNode().collapse(); }, expand: function() { this.getNode().expand(); }, getToolElement: Ext.emptyFn, insertItem: Ext.emptyFn, isExpanded: function() { return this.getExpanded(); }, isSelectionEvent: Ext.emptyFn, isToggleEvent: Ext.emptyFn, nodeCollapse: function(node, collapsingForExpand) { var me = this, owner = me.getOwner(), animation = me.preventAnimation ? null : owner.getAnimation(); me.nodeCollapseBegin(animation, collapsingForExpand); if (!animation) { me.nodeCollapseEnd(collapsingForExpand); } }, nodeCollapseBegin: function(animation, collapsingForExpand) { var me = this, owner = me.getOwner(); me.setExpanded(false); owner.fireEvent('itemcollapse', owner, me); }, nodeCollapseEnd: function(collapsingForExpand) { if (!collapsingForExpand && !this.destroying) { this.getOwner().updateLayout(); } }, nodeExpand: function(node) { var me = this, owner = me.getOwner(), floated = me.getFloated(), animation = !floated && owner.getAnimation(); me.nodeExpandBegin(animation); if (!animation) { me.nodeExpandEnd(); } }, nodeExpandBegin: function(animation) { var me = this, owner = me.getOwner(); me.setExpanded(true); owner.fireEvent('itemexpand', owner, me); }, nodeExpandEnd: function() { if (!this.destroying) { this.getOwner().updateLayout(); } }, nodeInsert: function(node, refNode) { var me = this, owner = me.getOwner(), map = me.itemMap, id = node.internalId, item = owner.getItem(node), refItem = null, oldParent; if (item) { oldParent = item.getParentItem(); oldParent.removeItem(item); if (oldParent !== me) { oldParent.doUpdateExpandable(); item.setParentItem(me); } } else { item = me.getOwner().createItem(node, me); } map[id] = item; if (refNode) { refItem = map[refNode.internalId]; } me.insertItem(item, refItem); me.doUpdateExpandable(); owner.fireEvent('iteminsert', owner, me, item, refItem); owner.updateLayout(); }, nodeRemove: function(node) { var me = this, map = me.itemMap, owner = me.getOwner(), id = node.internalId, item = map[id]; if (item) { delete map[id]; me.removeItem(item); item.destroy(); me.doUpdateExpandable(); owner.fireEvent('itemremove', owner, me, item); owner.updateLayout(); } }, nodeUpdate: function(node, modifiedFieldNames) { this.doNodeUpdate(node); }, onClick: function(e) { var me = this, owner = me.getOwner(), node = me.getNode(), info = { event: e, item: me, node: node, tree: owner, select: node.get('selectable') !== false && me.isSelectionEvent(e), toggle: me.isToggleEvent(e) }; if (owner.fireEvent('itemclick', owner, info) !== false) { if (info.toggle) { me.toggleExpanded(); e.preventDefault(); } if (info.select) { owner.setSelection(me.getNode()); } } }, removeItem: Ext.emptyFn, destroy: function() { var me = this, map = me.itemMap, owner = me.getOwner(), key; if (map) { for (key in map) { map[key].destroy(); } me.itemMap = null; } if (owner) { owner.removeItem(me.getNode()); } me.setNode(null); me.setParentItem(null); me.setOwner(null); me.callParent(); }, privates: { doNodeUpdate: function(node, modifiedFieldNames) { var me = this, textProperty = this.getTextProperty(), iconClsProperty = this.getIconClsProperty(); if (textProperty) { me.setText(node.data[textProperty]); } if (iconClsProperty) { me.setIconCls(node.data[iconClsProperty]); } me.setLoading(node.isLoading()); me.setLeaf(node.isLeaf()); me.doUpdateExpandable(); }, doUpdateExpandable: function() { var node = this.getNode(); this.setExpandable(node.isExpandable()); }, toggleExpanded: function() { if (this.isExpanded()) { this.collapse(); } else { this.expand(); } }, updateIndent: function(value) { var items = this.itemMap, id; for (id in items) { items[id].setIndent(value); } }, updateOwner: function(owner) { this.parent = owner; } } }); Ext.define('Ext.list.RootTreeItem', { extend: Ext.list.AbstractTreeItem, isRootListItem: true, element: { reference: 'element', tag: 'ul', cls: Ext.baseCSSPrefix + 'treelist-root-container' }, insertItem: function(item, refItem) { if (refItem) { item.element.insertBefore(refItem.element); } else { this.element.appendChild(item.element); } }, isToggleEvent: function(e) { return false; } }); Ext.define('Ext.mixin.ItemRippler', { mixinId: 'itemrippler', config: { itemRipple: null }, shouldRippleItem: function(item, e) { var itemRipple, ripple; if (e.getTarget(this.noItemRippleSelector, this.element)) { return false; } itemRipple = item && this.getItemRipple(); if (itemRipple && item.isWidget) { ripple = item.shouldRipple(e); if (ripple) { itemRipple = Ext.apply({}, itemRipple, ripple); } } return itemRipple; }, rippleItem: function(item, e) { if (!item) { return; } var me = this, start = e.type.match(me.rippleStateRe), itemRipple = me.shouldRippleItem(item, e), release = itemRipple && itemRipple.release, isRelease = release === true, el = item.isWidget ? item.el : item, pos, delta, rs, rippledItems; if (itemRipple && start && isRelease) { me.$rippleStart = e.getXY(); } if (itemRipple && el && ((!start && isRelease) || (start && release !== true))) { rippledItems = me.$rippledItems || (me.$rippledItems = []); rs = me.$rippleStart; if (rs) { pos = e.getXY(); delta = Math.sqrt(Math.pow((pos[0] - rs[0]), 2) + Math.pow((pos[1] - rs[1]), 2)); if (delta <= 8) { el.ripple(e, itemRipple); rippledItems.push(el); } } else { el.ripple(e, itemRipple); rippledItems.push(el); } me.$rippleStart = null; } }, destroyAllRipples: function() { for (var items = this.$rippledItems; items && items.length; ) { items.pop().destroyAllRipples(); } }, privates: { noItemRippleSelector: '.' + Ext.baseCSSPrefix + 'item-no-ripple, ' + '.' + Ext.baseCSSPrefix + 'item-no-tap', rippleStateRe: /start|down/ } }); Ext.define('Ext.list.TreeItem', { extend: Ext.list.AbstractTreeItem, xtype: 'treelistitem', collapsedCls: Ext.baseCSSPrefix + 'treelist-item-collapsed', expandedCls: Ext.baseCSSPrefix + 'treelist-item-expanded', floatedToolCls: Ext.baseCSSPrefix + 'treelist-item-tool-floated', leafCls: Ext.baseCSSPrefix + 'treelist-item-leaf', expandableCls: Ext.baseCSSPrefix + 'treelist-item-expandable', hideIconCls: Ext.baseCSSPrefix + 'treelist-item-hide-icon', loadingCls: Ext.baseCSSPrefix + 'treelist-item-loading', selectedCls: Ext.baseCSSPrefix + 'treelist-item-selected', selectedParentCls: Ext.baseCSSPrefix + 'treelist-item-selected-parent', withIconCls: Ext.baseCSSPrefix + 'treelist-item-with-icon', hoverCls: Ext.baseCSSPrefix + 'treelist-item-over', rowHoverCls: Ext.baseCSSPrefix + 'treelist-row-over', isTreeListItem: true, config: { rowCls: null }, rowClsProperty: 'rowCls', element: { reference: 'element', tag: 'li', cls: Ext.baseCSSPrefix + 'treelist-item', children: [ { reference: 'rowElement', cls: Ext.baseCSSPrefix + 'treelist-row', children: [ { reference: 'wrapElement', cls: Ext.baseCSSPrefix + 'treelist-item-wrap', children: [ { reference: 'iconElement', cls: Ext.baseCSSPrefix + 'treelist-item-icon' }, { reference: 'textElement', cls: Ext.baseCSSPrefix + 'treelist-item-text' }, { reference: 'expanderElement', cls: Ext.baseCSSPrefix + 'treelist-item-expander' } ] } ] }, { reference: 'itemContainer', tag: 'ul', cls: Ext.baseCSSPrefix + 'treelist-container' }, { reference: 'toolElement', cls: Ext.baseCSSPrefix + 'treelist-item-tool' } ] }, constructor: function(config) { this.callParent([ config ]); var toolDom = this.toolElement.dom; toolDom.parentNode.removeChild(toolDom); }, getToolElement: function() { return this.toolElement; }, insertItem: function(item, refItem) { if (refItem) { item.element.insertBefore(refItem.element); } else { this.itemContainer.appendChild(item.element); } }, isSelectionEvent: function(e) { var owner = this.getOwner(); return (!this.isToggleEvent(e) || !owner.getExpanderOnly() || owner.getSelectOnExpander()); }, isToggleEvent: function(e) { var isExpand = false; if (this.getOwner().getExpanderOnly()) { isExpand = e.target === this.expanderElement.dom; } else { isExpand = !this.itemContainer.contains(e.target); } return isExpand; }, nodeCollapseBegin: function(animation, collapsingForExpand) { var me = this, itemContainer = me.itemContainer, height; if (me.expanding) { me.stopAnimation(me.expanding); } height = animation && itemContainer.getHeight(); me.callParent([ animation, collapsingForExpand ]); if (animation) { itemContainer.dom.style.display = 'block'; me.collapsingForExpand = collapsingForExpand; me.collapsing = this.runAnimation(Ext.merge({ from: { height: height }, to: { height: 0 }, callback: me.nodeCollapseDone, scope: me }, animation)); } }, nodeCollapseDone: function(animation) { var me = this, itemContainer = me.itemContainer; if (!me.destroying && !me.destroyed) { me.collapsing = null; itemContainer.dom.style.display = ''; itemContainer.setHeight(null); me.nodeCollapseEnd(me.collapsingForExpand); } }, nodeExpandBegin: function(animation) { var me = this, itemContainer = me.itemContainer, height; if (me.collapsing) { me.stopAnimation(me.collapsing); } me.callParent([ animation ]); if (animation) { height = itemContainer.getHeight(); itemContainer.setHeight(0); me.expanding = me.runAnimation(Ext.merge({ to: { height: height }, callback: me.nodeExpandDone, scope: me }, animation)); } }, nodeExpandDone: function() { this.expanding = null; this.itemContainer.setHeight(null); this.nodeExpandEnd(); }, removeItem: function(item) { this.itemContainer.removeChild(item.element); }, updateNode: function(node, oldNode) { this.syncIndent(); this.callParent([ node, oldNode ]); }, updateExpandable: function(expandable) { var node = this.getNode(); this.updateExpandCls(); if (node) { node.set('expandable', expandable); } }, updateExpanded: function(expanded) { var node = this.getNode(); this.updateExpandCls(); if (node) { node.set('expanded', expanded); } }, updateIconCls: function(iconCls, oldIconCls) { var me = this, el = me.element; me.doIconCls(me.iconElement, iconCls, oldIconCls); me.doIconCls(me.toolElement, iconCls, oldIconCls); el.toggleCls(me.withIconCls, !!iconCls); el.toggleCls(me.hideIconCls, iconCls === null); }, updateLeaf: function(leaf) { this.element.toggleCls(this.leafCls, leaf); }, updateLoading: function(loading) { this.element.toggleCls(this.loadingCls, loading); }, updateOver: function(over) { var me = this; me.element.toggleCls(me.hoverCls, !!over); me.rowElement.toggleCls(me.rowHoverCls, over > 1); }, updateRowCls: function(value, oldValue) { this.rowElement.replaceCls(oldValue, value); }, updateSelected: function(selected, oldSelected) { var me = this, cls = me.selectedCls, tool = me.getToolElement(); me.callParent([ selected, oldSelected ]); me.element.toggleCls(cls, selected); if (tool) { tool.toggleCls(cls, selected); } }, updateSelectedParent: function(selectedParent) { var me = this; me.element.toggleCls(me.selectedParentCls, selectedParent); var tool = me.getToolElement(); if (tool) { tool.toggleCls(me.selectedCls, selectedParent); } }, updateText: function(text) { this.textElement.update(text); }, privates: { doNodeUpdate: function(node) { this.callParent([ node ]); this.setRowCls(node && node.data[this.rowClsProperty]); }, doIconCls: function(element, iconCls, oldIconCls) { if (oldIconCls) { element.removeCls(oldIconCls); } if (iconCls) { element.addCls(iconCls); } }, syncIndent: function() { var me = this, indent = me.getIndent(), node = me.getNode(), depth; if (node) { depth = node.data.depth - 1; me.wrapElement.dom.style.marginLeft = (depth * indent) + 'px'; } }, updateExpandCls: function() { if (!this.updatingExpandCls) { var me = this, expandable = me.getExpandable(), element = me.element, expanded = me.getExpanded(), expandedCls = me.expandedCls, collapsedCls = me.collapsedCls; me.updatingExpandCls = true; element.toggleCls(me.expandableCls, expandable); if (expandable) { element.toggleCls(expandedCls, expanded); element.toggleCls(collapsedCls, !expanded); } else { element.removeCls([ expandedCls, collapsedCls ]); } me.updatingExpandCls = false; } }, updateIndent: function(value, oldValue) { this.syncIndent(); this.callParent([ value, oldValue ]); } } }, function(TreeItem) { TreeItem.prototype.floatedCls = [ Ext.Widget.prototype.floatedCls, Ext.baseCSSPrefix + 'treelist-item-floated' ]; }); Ext.define('Ext.list.Tree', { extend: Ext.Gadget, xtype: 'treelist', mixins: [ Ext.mixin.ItemRippler ], expanderFirstCls: Ext.baseCSSPrefix + 'treelist-expander-first', expanderOnlyCls: Ext.baseCSSPrefix + 'treelist-expander-only', highlightPathCls: Ext.baseCSSPrefix + 'treelist-highlight-path', microCls: Ext.baseCSSPrefix + 'treelist-micro', uiPrefix: Ext.baseCSSPrefix + 'treelist-', element: { reference: 'element', cls: Ext.baseCSSPrefix + 'treelist ' + Ext.baseCSSPrefix + 'unselectable', listeners: { click: 'onClick', touchstart: 'onTouchStart', touchend: 'onTouchEnd', mouseenter: 'onMouseEnter', mouseleave: 'onMouseLeave', mouseover: 'onMouseOver' }, children: [ { reference: 'toolsElement', cls: Ext.baseCSSPrefix + 'treelist-toolstrip', listeners: { click: 'onToolStripClick', mouseover: 'onToolStripMouseOver' } } ] }, cachedConfig: { animation: { duration: 500, easing: 'ease' }, expanderFirst: true, expanderOnly: true }, config: { floatLeafItems: false, defaults: { xtype: 'treelistitem' }, highlightPath: null, iconSize: null, indent: null, micro: false, overItem: null, selection: null, selectOnExpander: false, singleExpand: null, store: null, ui: null }, twoWayBindable: { selection: 1 }, publishes: { selection: 1 }, defaultBindProperty: 'store', constructor: function(config) { this.callParent([ config ]); this.publishState('selection', this.getSelection()); }, destroy: function() { var me = this; me.unfloatAll(); me.activeFloater = null; me.setSelection(null); me.setStore(null); me.callParent(); }, updateOverItem: function(over, wasOver) { var map = {}, state = 2, c, node; for (c = over; c; c = this.getItem(node.parentNode)) { node = c.getNode(); map[node.internalId] = true; c.setOver(state); state = 1; } if (wasOver && !wasOver.destroyed) { for (c = wasOver; c; c = this.getItem(node.parentNode)) { node = c.getNode(); if (map[node.internalId]) { break; } c.setOver(0); } } }, applyMicro: function(micro) { return Boolean(micro); }, applySelection: function(selection, oldSelection) { var store = this.getStore(); if (!store) { selection = null; } if (store && selection !== null && !(selection instanceof Ext.data.Model)) { selection = store.getNodeById(selection); } if (selection && selection.get('selectable') === false) { selection = oldSelection; } return selection; }, updateSelection: function(selection, oldSelection) { var me = this, item, parent; if (!me.destroying) { item = me.getItem(oldSelection); if (item) { item.setSelected(false); } item = me.getItem(selection); if (item) { item.setSelected(true); while (parent = item.getParentItem()) { parent.setExpanded(true); item = parent; } } me.fireEvent('selectionchange', me, selection); } }, applyStore: function(store) { return store && Ext.StoreManager.lookup(store, 'tree'); }, updateStore: function(store, oldStore) { var me = this, root; if (oldStore) { if (!oldStore.destroyed) { if (oldStore.getAutoDestroy()) { oldStore.destroy(); } else { me.storeListeners.destroy(); } } me.removeRoot(); me.storeListeners = null; } if (store) { me.storeListeners = store.on({ destroyable: true, scope: me, filterchange: 'onFilterChange', nodeappend: 'onNodeAppend', nodecollapse: 'onNodeCollapse', nodeexpand: 'onNodeExpand', nodeinsert: 'onNodeInsert', noderemove: 'onNodeRemove', rootchange: 'onRootChange', update: 'onNodeUpdate' }); root = store.getRoot(); if (root) { me.createRootItem(root); } } if (!me.destroying) { me.updateLayout(); } }, updateExpanderFirst: function(expanderFirst) { this.element.toggleCls(this.expanderFirstCls, expanderFirst); }, updateExpanderOnly: function(value) { this.element.toggleCls(this.expanderOnlyCls, !value); }, updateHighlightPath: function(updatePath) { this.element.toggleCls(this.highlightPathCls, updatePath); }, updateMicro: function(micro) { var me = this; if (!micro) { me.unfloatAll(); me.activeFloater = null; } me.element.toggleCls(me.microCls, micro); }, updateUi: function(ui, oldValue) { var me = this, el = me.element, uiPrefix = me.uiPrefix; if (oldValue) { el.removeCls(uiPrefix + oldValue); } if (ui) { el.addCls(uiPrefix + ui); } delete me.iconSize; me.syncIconSize(); }, getItem: function(node) { var map = this.itemMap, ret; if (node && map) { ret = map[node.internalId]; } return ret || null; }, getItemConfig: function(node, parent) { return Ext.apply({ parentItem: parent.isRootListItem ? null : parent, owner: this, node: node, indent: this.getIndent() }, this.getDefaults()); }, privates: { checkForOutsideClick: function(e) { var floater = this.activeFloater; if (!floater.element.contains(e.target)) { this.unfloatAll(); } }, collapsingForExpand: false, createItem: function(node, parent) { var me = this, item = Ext.create(me.getItemConfig(node, parent)), toolsElement = me.toolsElement, toolEl, previousSibling; if (parent.isRootListItem) { toolEl = item.getToolElement(); if (toolEl) { previousSibling = me.findVisiblePreviousSibling(node); if (!previousSibling) { toolsElement.insertFirst(toolEl); } else { previousSibling = me.getItem(previousSibling); toolEl.insertAfter(previousSibling.getToolElement()); } toolEl.dom.setAttribute('data-recordId', node.internalId); toolEl.isTool = true; } } me.itemMap[node.internalId] = item; return item; }, createRootItem: function(root) { var me = this, item; me.itemMap = {}; me.rootItem = item = new Ext.list.RootTreeItem({ indent: me.getIndent(), node: root, owner: me }); me.element.appendChild(item.element); me.itemMap[root.internalId] = item; }, findVisiblePreviousSibling: function(node) { var sibling = node.previousSibling; while (sibling) { if (sibling.data.visible) { return sibling; } sibling = sibling.previousSibling; } return null; }, floatItem: function(item, byHover) { var me = this, floater; if (item.getFloated()) { return; } if (me.toolMouseListeners) { me.toolMouseListeners.destroy(); me.floaterMouseListeners.destroy(); me.floaterMouseListeners = me.toolMouseListeners = null; } me.unfloatAll(); if (!byHover && !me.getFloatLeafItems() && item.getNode().isLeaf()) { return; } me.activeFloater = floater = item; me.floatedByHover = byHover; item.setFloated(true); if (byHover) { me.toolMouseListeners = item.getToolElement().monitorMouseLeave(300, me.checkForMouseLeave, me); me.floaterMouseListeners = (item.floater || item).el.monitorMouseLeave(300, me.checkForMouseLeave, me); floater.element.on('mouseover', 'onMouseOver', me); } else { Ext.on('mousedown', 'checkForOutsideClick', me); } }, shouldRippleItem: function(item, e) { if (item && item.getSelected()) { return false; } return this.mixins.itemrippler.shouldRippleItem.call(this, item, e); }, onTouchStart: function(e) { this.doItemRipple(e); }, onTouchEnd: function(e) { this.doItemRipple(e); }, doItemRipple: function(e) { var me = this, item = e.getTarget('[data-recordId]'), id; if (item) { id = item.getAttribute('data-recordId'); item = me.itemMap[id]; if (item && me.shouldRippleItem(item, e)) { this.rippleItem(item, e); } } }, onClick: function(e) { var item = e.getTarget('[data-recordId]'), id; if (item) { id = item.getAttribute('data-recordId'); item = this.itemMap[id]; if (item) { item.onClick(e); } } }, onMouseEnter: function(e) { this.onMouseOver(e); }, onMouseLeave: function() { this.setOverItem(null); }, onMouseOver: function(e) { var comp = Ext.Component.from(e); this.setOverItem(comp && comp.isTreeListItem && comp); }, checkForMouseLeave: function(e) { var floater = this.activeFloater, relatedTarget = e.getRelatedTarget(); if (floater) { if (relatedTarget !== floater.getToolElement().dom && !floater.element.contains(relatedTarget)) { this.unfloatAll(); } } }, onFilterChange: function(store) { this.onRootChange(store.getRoot()); }, onNodeAppend: function(parentNode, node) { if (parentNode) { var item = this.itemMap[parentNode.internalId]; if (item) { item.nodeInsert(node, null); } } }, onNodeCollapse: function(node) { var item = this.itemMap[node.internalId]; if (item) { item.nodeCollapse(node, this.collapsingForExpand); } }, onNodeExpand: function(node) { var me = this, item = me.itemMap[node.internalId], childNodes, len, i, parentNode, child; if (item) { if (!item.isRootItem && me.getSingleExpand()) { me.collapsingForExpand = true; parentNode = (item.getParentItem() || me.rootItem).getNode(); childNodes = parentNode.childNodes; for (i = 0 , len = childNodes.length; i < len; ++i) { child = childNodes[i]; if (child !== node) { child.collapse(); } } me.collapsing = false; } item.nodeExpand(node); } }, onNodeInsert: function(parentNode, node, refNode) { var item = this.itemMap[parentNode.internalId]; if (item) { item.nodeInsert(node, refNode); } }, onNodeRemove: function(parentNode, node, isMove) { if (parentNode && !isMove) { var item = this.itemMap[parentNode.internalId]; if (item) { item.nodeRemove(node); } } }, onNodeUpdate: function(store, node, type, modifiedFieldNames) { var item = this.itemMap[node.internalId]; if (item) { item.nodeUpdate(node, modifiedFieldNames); } }, onRootChange: function(root) { var me = this; me.removeRoot(); if (root) { me.createRootItem(root); } me.updateLayout(); me.fireEvent('refresh', me); }, removeItem: function(node) { var map = this.itemMap, id = node.internalId, item, toolEl; if (map) { item = map[id]; if (item.getParentItem() === null) { toolEl = item.getToolElement(); if (toolEl) { this.toolsElement.removeChild(toolEl); } } delete map[id]; } }, removeRoot: function() { var me = this, rootItem = me.rootItem; if (rootItem) { me.element.removeChild(rootItem.element); me.rootItem = me.itemMap = Ext.destroy(rootItem); } }, onToolStripClick: function(e) { var item = e.getTarget('[data-recordId]'), id; if (item) { id = item.getAttribute('data-recordId'); item = this.itemMap[id]; if (item) { if (item === this.activeFloater) { this.unfloatAll(); } else { this.floatItem(item, false); } } } }, onToolStripMouseOver: function(e) { var item = e.getTarget('[data-recordId]'), id; if (item) { id = item.getAttribute('data-recordId'); item = this.itemMap[id]; if (item) { this.floatItem(item, true); } } }, syncIconSize: function() { var me = this, size = me.iconSize || (me.iconSize = parseInt(me.element.getStyle('background-position'), 10)); me.setIconSize(size); }, unfloatAll: function() { var me = this, floater = me.activeFloater; if (floater) { floater.setFloated(false); me.activeFloater = null; if (me.floatedByHover) { if (me.toolMouseListeners) { me.toolMouseListeners.destroy(); me.floaterMouseListeners.destroy(); me.floaterMouseListeners = me.toolMouseListeners = null; } floater.element.un('mouseover', 'onMouseOver', me); } else { Ext.un('mousedown', 'checkForOutsideClick', me); } } }, defaultIconSize: 22, updateIconSize: function(value) { this.setIndent(value || this.defaultIconSize); }, updateIndent: function(value) { var rootItem = this.rootItem; if (rootItem) { rootItem.setIndent(value); } } } }); Ext.define('Ext.mixin.ConfigProxy', function(ConfigProxy) { return { extend: Ext.Mixin, mixinConfig: { id: 'configproxy', extended: function(baseClass, derivedClass, classBody) { var proxyConfig = classBody.proxyConfig; derivedClass.$configProxies = Ext.apply({}, derivedClass.superclass.self.$configProxies); if (proxyConfig) { delete classBody.proxyConfig; ConfigProxy.processClass(derivedClass, proxyConfig); } } }, onClassMixedIn: function(targetClass) { var prototype = targetClass.prototype, proxyConfig = prototype.proxyConfig, initConfig = prototype.initConfig; prototype.$proxiedConfigs = null; targetClass.$configProxies = {}; prototype.initConfig = function(config) { initConfig.apply(this, arguments); this.$proxiedConfigs = null; return this; }; if (proxyConfig) { delete prototype.proxyConfig; ConfigProxy.processClass(targetClass, proxyConfig); } }, getProxiedConfigs: function(name) { var me = this, configs = me.config, configProxies = me.self.$configProxies[name], i = configProxies && configProxies.length, cfg, proxiedConfigs, ret, s, v; if (i && me.isConfiguring) { proxiedConfigs = me.$proxiedConfigs || (me.$proxiedConfigs = {}); while (i-- > 0) { cfg = configProxies[i]; proxiedConfigs[s = cfg.name] = cfg; if ((v = configs[s]) !== undefined) { (ret || (ret = {}))[s] = v; } } } return ret; }, mergeProxiedConfigs: function(name, itemConfig, alwaysClone) { var me = this, ret = itemConfig, proxied = me.getProxiedConfigs(name), configurator; if (proxied) { if (!itemConfig) { ret = proxied; } else if (itemConfig.constructor === Object) { configurator = me.self.getConfigurator(); ret = configurator.merge(me, Ext.clone(itemConfig), proxied); } } if (alwaysClone && ret === itemConfig) { ret = Ext.clone(ret); } return ret; }, statics: { processClass: function(targetClass, proxyConfig) { var ExtConfig = Ext.Config, targetProto = targetClass.prototype, add = {}, proxies = targetClass.$configProxies, cfg, configs, itemGetter, i, item, methods, n, name, proxiedConfigs, s; for (item in proxyConfig) { itemGetter = ExtConfig.get(item).names.get; configs = proxyConfig[item]; if (Ext.isArray(configs)) { methods = null; } else { methods = configs.methods; configs = configs.configs; } if (!(proxiedConfigs = proxies[item])) { proxies[item] = proxiedConfigs = []; } else { proxies[item] = proxiedConfigs = proxiedConfigs.slice(); } for (i = 0 , n = methods && methods.length; i < n; ++i) { if (!targetProto[name = methods[i]]) { targetProto[name] = ConfigProxy.wrapFn(itemGetter, name); } else { Ext.raise('Cannot proxy method "' + name + '"'); } } for (i = 0 , n = configs && configs.length; i < n; ++i) { cfg = ExtConfig.get(s = configs[i]); if (s in add) { Ext.raise('Duplicate proxy config definitions for "' + s + '"'); } if (s in targetProto.config) { Ext.raise('Config "' + s + '" already defined for class ' + targetProto.$className); } add[s] = undefined; proxiedConfigs.push(cfg); if (!targetProto[name = cfg.names.get]) { targetProto[name] = ConfigProxy.wrapGet(itemGetter, name); } else { Ext.raise('Cannot proxy "' + s + '" config getter'); } if (!targetProto[name = cfg.names.set]) { targetProto[name] = ConfigProxy.wrapSet(itemGetter, name, s); } else { Ext.raise('Cannot proxy "' + s + '" config setter'); } } } targetClass.addConfig(add); }, wrapFn: function(itemGetter, name) { return function() { var item = this[itemGetter](); return item && item[name].apply(item, arguments); }; }, wrapGet: function(itemGetter, configGetter) { return function() { var item = this[itemGetter](); return item && item[configGetter](); }; }, wrapSet: function(itemGetter, configSetter, itemName) { return function(value) { var me = this, item, proxiedConfigs; if (!me.isConfiguring || value !== undefined) { item = me[itemGetter](); proxiedConfigs = me.$proxiedConfigs; if (proxiedConfigs && proxiedConfigs[itemName]) { delete proxiedConfigs[itemName]; item = null; } if (item) { item[configSetter](value); } } return me; }; } } }; }); Ext.define('Ext.mixin.ConfigState', { extend: Ext.Mixin, mixinConfig: { id: 'configstate' }, alternateStateConfig: '', toggleConfigState: function(isAlternate) { var me = this, state = me.capturedConfigState, cfg = me.getConfig(me.alternateStateConfig), key; if (!cfg) { return; } if (isAlternate) { state = {}; for (key in cfg) { state[key] = me.getConfig(key); } me.capturedConfigState = state; me.setConfig(cfg); } else if (!me.isConfiguring && state) { me.setConfig(state); delete me.capturedConfigState; } } }); 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, xtypes = targetClass.prototype.xtypes, mashup = Ext.manifest.mashup || {}, options = body.mashupConfig, i, script; if (requiredScripts) { delete body.requiredScripts; hooks.onCreated = function() { var me = this, scripts = [], args = Ext.Array.slice(arguments), redirect = mashup.redirect || {}; requiredScripts = scripts.concat(requiredScripts); options = options && mashup[options.key]; if (xtypes) { for (i = 0; !options && i < xtypes.length; ++i) { options = mashup[xtypes[i]]; } } for (i = 0; i < requiredScripts.length; i++) { script = requiredScripts[i]; if (redirect[script] === false) { continue; } script = redirect[script] || script; if (script.indexOf('{') > -1) { if (options) { script = new Ext.Template(script).apply(options); } else { Ext.log.error('Missing mashup options for ' + body.$className + ' script "' + script + '"'); } } scripts.push(script); } if (!scripts.length) { hooks.onCreated = onCreated; hooks.onCreated.call(me, args); return; } Ext.Loader.loadScripts({ url: scripts, cache: true, onError: function(opts, error) { targetClass.scriptError = targetClass.prototype.scriptError = error; hooks.onCreated = onCreated; hooks.onCreated.call(me, args); }, 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, 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); }, 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 = Ext.unasap(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.asap(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.self.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, selected: true, pruneRemoved: true, selection: null, twoWayBindable: { selection: 1 }, publishes: { selection: 1 } }, modes: { SINGLE: true, SIMPLE: true, MULTI: true }, onNavigate: function(event) {}, selectableEventHooks: { add: 'onSelectionStoreAdd', remove: 'onSelectionStoreRemove', update: 'onSelectionStoreUpdate', clear: { fn: 'onSelectionStoreClear', priority: 1000 }, load: 'refreshSelection', refresh: 'refreshSelection' }, initSelectable: function() { this.publishState('selection', this.getSelection()); }, applySelected: function(selected) { if (!selected.isCollection) { selected = new Ext.util.Collection(selected); } selected.addObserver(this); return selected; }, 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.on(bindEvents); me.refreshSelection(); } }, selectAll: function(silent) { var me = this, selections = me.getStore().getRange(); me.select(selections, true, silent); }, deselectAll: function(supress) { var me = this; me.deselect(me.getSelected().getRange(), supress); me.setLastSelected(null); me.setLastFocused(null); }, updateSelection: function(selection) { if (this.changingSelection) { return; } if (selection) { this.select(selection); } else { this.deselectAll(); } }, 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) { this.doMultiSelect([ record ], false, suppressEvent); }, doMultiSelect: function(records, keepExisting, suppressEvent) { if (records === null || this.getDisableSelection()) { return; } records = !Ext.isArray(records) ? [ records ] : records; var me = this, selected = me.getSelected(), selectionCount = selected.getCount(), toRemove = [], ln = records.length, change = false, i = 0, record; if (!keepExisting && selectionCount) { toRemove = selected.getRange(); } for (i = 0; i < ln; i++) { record = records[i]; if (typeof record === 'number') { records[i] = store.getAt(record); } } selected.suppressEvent = suppressEvent; selected.splice(selectionCount, toRemove, records); selected.suppressEvent = false; }, deselect: function(records, suppressEvent) { var me = this; if (me.getDisableSelection()) { return; } records = Ext.isArray(records) ? records : [ records ]; var selected = me.getSelected(), store = me.getStore(), len = records.length, i, record; for (i = 0; i < len; i++) { record = records[i]; if (typeof record === 'number') { records[i] = store.getAt(record); } } selected.suppressEvent = suppressEvent; selected.remove(records); selected.suppressEvent = false; }, onCollectionRemove: function(selectedCollection, chunk) { var me = this, lastSelected = me.getLastSelected(), records = chunk.items; if (lastSelected && !selectedCollection.contains(lastSelected)) { me.setLastSelected(selectedCollection.last()); } me.onItemDeselect(records, selectedCollection.suppressEvent); if (!selectedCollection.suppressEvent) { me.fireSelectionChange(records); } }, onCollectionAdd: function(selectedCollection, adds) { var me = this, records = adds.items; me.setLastSelected(selectedCollection.last()); me.onItemSelect(records, selectedCollection.suppressEvent); if (!selectedCollection.suppressEvent) { me.fireSelectionChange(records); } }, updateLastFocused: function(newRecord, oldRecord) { this.onLastFocusChanged(oldRecord, newRecord); }, fireSelectionChange: function(records) { var me = this; me.changingSelection = true; me.setSelection(me.getLastSelected() || null); me.changingSelection = false; me.fireAction('selectionchange', [ me, records ], 'getSelections'); }, getSelections: function() { return this.getSelected().getRange(); }, isSelected: function(record) { record = Ext.isNumber(record) ? this.getStore().getAt(record) : record; return this.getSelected().indexOf(record) !== -1; }, hasSelection: function() { return this.getSelected().getCount() > 0; }, refreshSelection: function() { var me = this, selected = me.getSelected(), selections = selected.getRange(), selectionLength = selections.length, storeCollection = me.getStore().getData(), toDeselect = [], toReselect = [], i, rec, matchingSelection; if (me.getPruneRemoved()) { storeCollection = storeCollection.getSource() || storeCollection; for (i = 0; i < selectionLength; i++) { rec = selections[i]; matchingSelection = storeCollection.get(storeCollection.getKey(rec)); if (matchingSelection) { if (matchingSelection !== rec) { toDeselect.push(rec); toReselect.push(matchingSelection); } } else { toDeselect.push(rec); } } } selected.suppressEvent = true; selected.splice(selected.getCount(), toDeselect, toReselect); selected.suppressEvent = false; }, onSelectionStoreRemove: function(store, records) { var me = this, selected = me.getSelected(), ln = records.length, removed, 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); } removed = removed || []; removed.push(record); } } if (removed) { me.fireSelectionChange([ removed ]); } }, onSelectionStoreClear: function(store) { var records = store.getData().items; this.onSelectionStoreRemove(store, records); }, getSelectionCount: function() { return this.getSelected().getCount(); }, onSelectionStoreAdd: Ext.emptyFn, onSelectionStoreUpdate: Ext.emptyFn, onItemSelect: Ext.emptyFn, onItemDeselect: Ext.emptyFn, onLastFocusChanged: Ext.emptyFn, onEditorKey: Ext.emptyFn }, function() {}); Ext.define('Ext.mixin.StoreWatcher', { mixinId: 'storewatcher', config: { dataSource: null, owner: null, ownerListeners: { destroyable: true, storechange: 'onStoreChange' }, sourceListeners: null, store: null, storeListeners: null }, afterClassMixedIn: function(targetClass) { var configurator = this.getConfigurator(), prototype = targetClass.prototype, config = {}, prop; for (prop in configurator.configs) { if (prototype.hasOwnProperty(prop)) { config[prop] = prototype[prop]; delete prototype[prop]; } } targetClass.addConfig(config); }, onFilterChange: function(store) { var source; if (!store) { source = null; } else if (store.getDataSource) { source = store.getDataSource(); } else { source = store.getData(); } this.setDataSource(source); }, onStoreChange: function(comp, store) { this.setStore(store); }, updateDataSource: function(source) { this.syncListeners(source, '$sourceListeners', 'getSourceListeners'); }, updateOwner: function(owner) { this.syncListeners(owner, '$ownerListeners', 'getOwnerListeners'); this.setStore(owner ? owner.getStore() : null); }, applyStore: function(store) { return (store && !store.isEmptyStore) ? store : null; }, updateStore: function(store) { this.syncListeners(store, '$storeListeners', 'getStoreListeners'); this.onFilterChange(store); }, privates: { syncListeners: function(instance, token, listeners) { var me = this, old = me[token]; if (old) { me[token] = null; old.destroy(); } if (instance) { listeners = me[listeners](); listeners = Ext.applyIf({ destroyable: true, scope: me }, listeners); me[token] = instance.on(listeners); } } } }); Ext.define('Ext.mixin.StyleCacher', { extend: Ext.Mixin, mixinConfig: { id: 'stylecacher' }, getCachedStyle: function(el, style) { var cache = this.$styleCache; if (!cache) { cache = this.$styleCache = {}; } if (!(style in cache)) { cache[style] = Ext.fly(el).getStyle(style); } return cache[style]; } }); 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 { 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', 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(); }, setupLog: function(config) { var className, cls, methods, method, override; for (className in config) { if (config.hasOwnProperty(className)) { cls = Ext.ClassManager.get(className); if (cls) { methods = config[className]; override = {}; for (method in methods) { override[method] = (function(methodName, idProp) { return function() { var before, diff, id, idHolder, ret; before = +Date.now(); ret = this.callParent(arguments); diff = +Date.now() - before; if (window.console && diff > 0) { idHolder = idProp === 'this' ? this : typeof idProp === 'string' ? this[idProp] : typeof idProp === 'number' ? arguments[idProp] : null; if (idHolder) { id = idHolder.id; } if (id != null) { console.log(methodName + ' for ' + id + ': ' + diff + 'ms'); } else { console.log(methodName + ' for unknown: ' + diff + 'ms'); } if (console.trace) { console.trace(); } } return ret; }; })(method, methods[method]); } Ext.override(cls, override); } } } } }); Ext.define('Ext.plugin.AbstractClipboard', { extend: Ext.plugin.Abstract, cachedConfig: { formats: { text: { get: 'getTextData', put: 'putTextData' } } }, config: { memory: null, source: 'system', system: 'text', gridListeners: null }, destroy: function() { var me = this, keyMap = me.keyMap, shared = me.shared; Ext.destroy(me.destroyListener); 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, listeners = me.getGridListeners(); if (comp.rendered) { me.finishInit(comp); } else if (listeners) { me.renderListener = comp.on(Ext.apply({ scope: me, destroyable: true, single: true }, listeners)); } }, onCmpReady: function() { this.renderListener = null; this.finishInit(this.getCmp()); }, getTarget: function(comp) { return comp.el; }, 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.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.raise('Invalid clipboard format "' + value[i] + '"'); } } } return value || null; }, applySystem: function(value) { var formats = this.getFormats(); if (!formats[value]) { Ext.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; if (me.validateAction(event) === false) { return; } 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: me.getTarget(comp), ignoreInputFields: true, 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; me.destroyListener = comp.on({ destroyable: true, 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.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.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, el; el = shared.textArea; if (!el) { el = shared.textArea = Ext.getBody().createChild({ tag: 'textarea', tabIndex: -1, style: { position: 'absolute', top: '-1000px', width: '1px', height: '1px' } }); el.suspendFocusEvents(); } return el; }, onCopy: function(keyCode, event) { this.doCutCopy(event, false); }, onCut: function(keyCode, event) { this.doCutCopy(event, true); }, onPaste: function(keyCode, event) { var me = this, sharedData = me.shared.data, source = me.getSource(), i, n, s; if (me.validateAction(event) === false) { return; } 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(true); area = me.getHiddenTextArea().dom; area.value = ''; if (focusEl) { focusEl.suspendFocusEvents(); } area.focus(); Ext.defer(function() { if (focusEl) { focusEl.focus(); focusEl.resumeFocusEvents(); } 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(true); area.value = data; if (focusEl) { focusEl.suspendFocusEvents(); } area.focus(); area.select(); Ext.defer(function() { area.value = ''; if (focusEl) { focusEl.focus(); focusEl.resumeFocusEvents(); } }, 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; }, validateAction: Ext.privateFn } }); Ext.define('Ext.plugin.MouseEnter', { extend: Ext.plugin.Abstract, alias: 'plugin.mouseenter', element: 'el', init: function(component) { if (!this.delegate) { Ext.raise('mouseenter plugin must be configured with a delegate selector'); } if (!this.handler) { Ext.raise('mouseenter plugin must be configured with handler callback'); } var me = this, listeners = { mouseover: 'onMouseEvent', scope: me, destroyable: true }, element = me.element; if (me.leaveHandler || me.delay) { listeners.mouseout = 'onMouseEvent'; } if (typeof element === 'string') { element = component[me.element]; } if (element) { me.mouseListener = Ext.get(element).on(listeners); } else { component.on({ render: function() { me.mouseListener = component[me.element].on(listeners); }, single: true }); } }, onMouseEvent: function(e) { var me = this, delegate = e.getTarget(me.delegate); if (delegate && delegate !== e.getRelatedTarget(me.delegate)) { if (me.delay) { Ext.undefer(me.mouseEventTimer); me.mouseEventTimer = Ext.defer(me.handleMouseEvent, me.delay, me, [ e, delegate ]); } else { me.handleMouseEvent(e, delegate); } } }, handleMouseEvent: function(e, delegate) { var me = this; if (e.type === 'mouseover') { Ext.callback(me.handler, null, [ e, delegate ], 0, me.cmp, me.scope); } else if (me.leaveHandler) { Ext.callback(me.leaveHandler, null, [ e, delegate ], 0, me.cmp, me.scope); } }, destroy: function() { Ext.destroy(this.mouseListener); this.callParent(); } }); Ext.define('Ext.sparkline.Shape', { constructor: function(target, id, type, args) { var me = this; me.target = target; me.id = id; me.type = type; me.args = args; }, append: function() { this.target.appendShape(this); return this; } }); Ext.define('Ext.sparkline.CanvasBase', { shapeCount: 0, _pxregex: /(\d+)(px)?\s*$/i, constructor: function(ownerSparkLine) { this.owner = ownerSparkLine; this.rtl = this.owner.getInherited().rtl; }, 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.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.raise('appendShape not implemented'); }, replaceWithShape: function(shapeid, shape) { Ext.raise('replaceWithShape not implemented'); }, insertAfterShape: function(shapeid, shape) { Ext.raise('insertAfterShape not implemented'); }, removeShapeId: function(shapeid) { Ext.raise('removeShapeId not implemented'); }, getShapeAt: function(x, y) { Ext.raise('getShapeAt not implemented'); }, render: function() { Ext.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) { if (this.rtl) { x = this.canvas.width - x - 1; } this.$moveTo(x * ratio, y * ratio); }, lineTo: function(x, y) { if (this.rtl) { x = this.canvas.width - x - 1; } this.$lineTo(x * ratio, y * ratio); }, arc: function(x, y, radius, startAngle, endAngle, counterclockwise) { if (this.rtl) { x = this.canvas.width - x - 1; } this.$arc(x * ratio, y * ratio, radius * ratio, startAngle, endAngle, counterclockwise); }, clearRect: function(x, y, width, height) { if (this.rtl) { x = this.canvas.width - x - width; } 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.context, overrides, name; if (!context) { this.context = context = this.el.dom.getContext('2d'); overrides = Ext.sparkline.CanvasCanvas.contextOverrides; for (name in overrides) { context['$' + name] = context[name]; } Ext.apply(context, overrides); context.rtl = this.rtl; } 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), xIncr = this.rtl ? -0.5 : 0.5, i, plen; context.beginPath(); context.moveTo(path[0][0] + xIncr, path[0][1] + 0.5); for (i = 1 , plen = path.length; i < plen; i++) { context.lineTo(path[i][0] + xIncr, 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 != null) { context.stroke(); } if (fillColor != null) { 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) { if (this.rtl) { x = this.el.dom.width - x - 1; } 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.util.Color', { alternateClassName: 'Ext.draw.Color', statics: { colorToHexRe: /(.*?)rgb\((\d+),\s*(\d+),\s*(\d+)\)/, rgbToHexRe: /\s*rgb\((\d+),\s*(\d+),\s*(\d+)\)/, rgbaToHexRe: /\s*rgba\((\d+),\s*(\d+),\s*(\d+),\s*([\.\d]+)\)/, hexRe: /\s*#([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)\s*/, NONE: 'none', RGBA_NONE: 'rgba(0, 0, 0, 0)' }, isColor: true, lightnessFactor: 0.2, constructor: function(red, green, blue, alpha) { this.setRGB(red, green, blue, alpha); }, clone: function() { var me = this; return new this.self(me.r, me.g, me.b, me.a); }, setRGB: function(red, green, blue, alpha) { var me = this; me.r = Math.min(255, Math.max(0, red)); me.g = Math.min(255, Math.max(0, green)); me.b = Math.min(255, Math.max(0, blue)); if (alpha === undefined) { me.a = 1; } else { me.a = Math.min(1, Math.max(0, alpha)); } }, getBrightness: function() { var r = this.r / 255 * 100, g = this.g / 255 * 100, b = this.b / 255 * 100; return ((r * 299) + (g * 587) + (b * 114)) / 1000; }, getGrayscale: function() { return this.r * 0.3 + this.g * 0.59 + this.b * 0.11; }, getHSL: function() { var me = this, r = me.r / 255, g = me.g / 255, b = me.b / 255, max = Math.max(r, g, b), min = Math.min(r, g, b), delta = max - min, h, s = 0, l = 0.5 * (max + min); if (min !== max) { s = (l <= 0.5) ? delta / (max + min) : delta / (2 - max - min); if (r === max) { h = 60 * (g - b) / delta; } else if (g === max) { h = 120 + 60 * (b - r) / delta; } else { h = 240 + 60 * (r - g) / delta; } if (h < 0) { h += 360; } if (h >= 360) { h -= 360; } } return [ h, s, l ]; }, getHSV: function() { var me = this, r = me.r / 255, g = me.g / 255, b = me.b / 255, max = Math.max(r, g, b), min = Math.min(r, g, b), C = max - min, h, s = 0, v = max; if (min != max) { s = v ? C / v : 0; if (r === max) { h = 60 * (g - b) / C; } else if (g === max) { h = 60 * (b - r) / C + 120; } else { h = 60 * (r - g) / C + 240; } if (h < 0) { h += 360; } if (h >= 360) { h -= 360; } } return [ h, s, v ]; }, setHSL: function(h, s, l) { var me = this, abs = Math.abs, c, x, m; h = (h % 360 + 360) % 360; s = s > 1 ? 1 : s < 0 ? 0 : s; l = l > 1 ? 1 : l < 0 ? 0 : l; if (s === 0 || h === null) { l *= 255; me.setRGB(l, l, l); } else { h /= 60; c = s * (1 - abs(2 * l - 1)); x = c * (1 - abs(h % 2 - 1)); m = l - c / 2; m *= 255; c *= 255; x *= 255; switch (Math.floor(h)) { case 0: me.setRGB(c + m, x + m, m); break; case 1: me.setRGB(x + m, c + m, m); break; case 2: me.setRGB(m, c + m, x + m); break; case 3: me.setRGB(m, x + m, c + m); break; case 4: me.setRGB(x + m, m, c + m); break; case 5: me.setRGB(c + m, m, x + m); break; } } return me; }, setHSV: function(h, s, v) { var me = this, c, x, m; h = (h % 360 + 360) % 360; s = s > 1 ? 1 : s < 0 ? 0 : s; v = v > 1 ? 1 : v < 0 ? 0 : v; if (s === 0 || h === null) { v *= 255; me.setRGB(v, v, v); } else { h /= 60; c = v * s; x = c * (1 - Math.abs(h % 2 - 1)); m = v - c; m *= 255; c *= 255; x *= 255; switch (Math.floor(h)) { case 0: me.setRGB(c + m, x + m, m); break; case 1: me.setRGB(x + m, c + m, m); break; case 2: me.setRGB(m, c + m, x + m); break; case 3: me.setRGB(m, x + m, c + m); break; case 4: me.setRGB(x + m, m, c + m); break; case 5: me.setRGB(c + m, m, x + m); break; } } return me; }, createLighter: function(factor) { var color = this.clone(); color.lighten(factor); return color; }, lighten: function(factor) { if (!factor && factor !== 0) { factor = this.lightnessFactor; } var hsl = this.getHSL(); this.setHSL(hsl[0], hsl[1], Ext.Number.constrain(hsl[2] + factor, 0, 1)); }, createDarker: function(factor) { var color = this.clone(); color.darken(factor); return color; }, darken: function(factor) { if (!factor && factor !== 0) { factor = this.lightnessFactor; } return this.lighten(-factor); }, toString: function() { var me = this, round = Math.round; if (me.a === 1) { var r = round(me.r).toString(16), g = round(me.g).toString(16), b = round(me.b).toString(16); r = (r.length === 1) ? '0' + r : r; g = (g.length === 1) ? '0' + g : g; b = (b.length === 1) ? '0' + b : b; return [ '#', r, g, b ].join(''); } else { return 'rgba(' + [ round(me.r), round(me.g), round(me.b), me.a === 0 ? 0 : me.a.toFixed(15) ].join(', ') + ')'; } }, toHex: function(color) { var r = this.r, g = this.g, b = this.b, rgb = b | (g << 8) | (r << 16); return '#' + ('000000' + rgb.toString(16)).slice(-6); }, setFromString: function(str) { var values, r, g, b, a = 1, parse = parseInt; if (str === Ext.util.Color.NONE) { this.r = this.g = this.b = this.a = 0; return this; } if ((str.length === 4 || str.length === 7) && str.substr(0, 1) === '#') { values = str.match(Ext.util.Color.hexRe); if (values) { r = parse(values[1], 16) >> 0; g = parse(values[2], 16) >> 0; b = parse(values[3], 16) >> 0; if (str.length === 4) { r += (r * 16); g += (g * 16); b += (b * 16); } } } else if ((values = str.match(Ext.util.Color.rgbToHexRe))) { r = +values[1]; g = +values[2]; b = +values[3]; } else if ((values = str.match(Ext.util.Color.rgbaToHexRe))) { r = +values[1]; g = +values[2]; b = +values[3]; a = +values[4]; } else { if (Ext.util.Color.ColorList.hasOwnProperty(str.toLowerCase())) { return this.setFromString(Ext.util.Color.ColorList[str.toLowerCase()]); } } if (typeof r === 'undefined') { return this; } this.r = r; this.g = g; this.b = b; this.a = a; return this; } }, function() { var flyColor = new this(); this.addStatics({ fly: function(red, green, blue, alpha) { switch (arguments.length) { case 1: flyColor.setFromString(red); break; case 3: case 4: flyColor.setRGB(red, green, blue, alpha); break; default: return null; } return flyColor; }, ColorList: { aliceblue: '#f0f8ff', antiquewhite: '#faebd7', aqua: '#00ffff', aquamarine: '#7fffd4', azure: '#f0ffff', beige: '#f5f5dc', bisque: '#ffe4c4', black: '#000000', blanchedalmond: '#ffebcd', blue: '#0000ff', blueviolet: '#8a2be2', brown: '#a52a2a', burlywood: '#deb887', cadetblue: '#5f9ea0', chartreuse: '#7fff00', chocolate: '#d2691e', coral: '#ff7f50', cornflowerblue: '#6495ed', cornsilk: '#fff8dc', crimson: '#dc143c', cyan: '#00ffff', darkblue: '#00008b', darkcyan: '#008b8b', darkgoldenrod: '#b8860b', darkgray: '#a9a9a9', darkgreen: '#006400', darkkhaki: '#bdb76b', darkmagenta: '#8b008b', darkolivegreen: '#556b2f', darkorange: '#ff8c00', darkorchid: '#9932cc', darkred: '#8b0000', darksalmon: '#e9967a', darkseagreen: '#8fbc8f', darkslateblue: '#483d8b', darkslategray: '#2f4f4f', darkturquoise: '#00ced1', darkviolet: '#9400d3', deeppink: '#ff1493', deepskyblue: '#00bfff', dimgray: '#696969', dodgerblue: '#1e90ff', firebrick: '#b22222', floralwhite: '#fffaf0', forestgreen: '#228b22', fuchsia: '#ff00ff', gainsboro: '#dcdcdc', ghostwhite: '#f8f8ff', gold: '#ffd700', goldenrod: '#daa520', gray: '#808080', green: '#008000', greenyellow: '#adff2f', honeydew: '#f0fff0', hotpink: '#ff69b4', indianred: '#cd5c5c', indigo: '#4b0082', ivory: '#fffff0', khaki: '#f0e68c', lavender: '#e6e6fa', lavenderblush: '#fff0f5', lawngreen: '#7cfc00', lemonchiffon: '#fffacd', lightblue: '#add8e6', lightcoral: '#f08080', lightcyan: '#e0ffff', lightgoldenrodyellow: '#fafad2', lightgray: '#d3d3d3', lightgrey: '#d3d3d3', lightgreen: '#90ee90', lightpink: '#ffb6c1', lightsalmon: '#ffa07a', lightseagreen: '#20b2aa', lightskyblue: '#87cefa', lightslategray: '#778899', lightsteelblue: '#b0c4de', lightyellow: '#ffffe0', lime: '#00ff00', limegreen: '#32cd32', linen: '#faf0e6', magenta: '#ff00ff', maroon: '#800000', mediumaquamarine: '#66cdaa', mediumblue: '#0000cd', mediumorchid: '#ba55d3', mediumpurple: '#9370d8', mediumseagreen: '#3cb371', mediumslateblue: '#7b68ee', mediumspringgreen: '#00fa9a', mediumturquoise: '#48d1cc', mediumvioletred: '#c71585', midnightblue: '#191970', mintcream: '#f5fffa', mistyrose: '#ffe4e1', moccasin: '#ffe4b5', navajowhite: '#ffdead', navy: '#000080', oldlace: '#fdf5e6', olive: '#808000', olivedrab: '#6b8e23', orange: '#ffa500', orangered: '#ff4500', orchid: '#da70d6', palegoldenrod: '#eee8aa', palegreen: '#98fb98', paleturquoise: '#afeeee', palevioletred: '#d87093', papayawhip: '#ffefd5', peachpuff: '#ffdab9', peru: '#cd853f', pink: '#ffc0cb', plum: '#dda0dd', powderblue: '#b0e0e6', purple: '#800080', red: '#ff0000', rosybrown: '#bc8f8f', royalblue: '#4169e1', saddlebrown: '#8b4513', salmon: '#fa8072', sandybrown: '#f4a460', seagreen: '#2e8b57', seashell: '#fff5ee', sienna: '#a0522d', silver: '#c0c0c0', skyblue: '#87ceeb', slateblue: '#6a5acd', slategray: '#708090', snow: '#fffafa', springgreen: '#00ff7f', steelblue: '#4682b4', tan: '#d2b48c', teal: '#008080', thistle: '#d8bfd8', tomato: '#ff6347', turquoise: '#40e0d0', violet: '#ee82ee', wheat: '#f5deb3', white: '#ffffff', whitesmoke: '#f5f5f5', yellow: '#ffff00', yellowgreen: '#9acd32' }, fromHSL: function(h, s, l) { return (new this(0, 0, 0, 0)).setHSL(h, s, l); }, fromHSV: function(h, s, v) { return (new this(0, 0, 0, 0)).setHSL(h, s, v); }, fromString: function(color) { return (new this(0, 0, 0, 0)).setFromString(color); }, create: function(arg) { if (arg instanceof this) { return arg; } else if (Ext.isArray(arg)) { return new Ext.util.Color(arg[0], arg[1], arg[2], arg[3]); } else if (Ext.isString(arg)) { return Ext.util.Color.fromString(arg); } else if (arguments.length > 2) { return new Ext.util.Color(arguments[0], arguments[1], arguments[2], arguments[3]); } else { return new Ext.util.Color(0, 0, 0, 0); } } }); }); Ext.define('Ext.sparkline.Base', { extend: Ext.Gadget, xtype: 'sparkline', cachedConfig: { lineColor: '#157fcc', defaultPixelsPerValue: 3, tagValuesAttribute: 'values', enableTagOptions: false, enableHighlight: true, highlightColor: null, highlightLighten: 0.1, tooltipSkipNull: true, tooltipPrefix: '', tooltipSuffix: '', disableTooltips: false, disableInteraction: false, tipTpl: null }, config: { values: null }, baseCls: Ext.baseCSSPrefix + 'sparkline', 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: { onClassCreated: function(cls) { var configUpdater = cls.prototype.updateConfigChange, proto = cls.prototype, configs = cls.getConfigurator().configs, config, updaterName; for (config in configs) { if (config !== 'tipTpl') { updaterName = Ext.Config.get(config).names.update; if (proto[updaterName]) { proto[updaterName] = Ext.Function.createSequence(proto[updaterName], configUpdater); } else { proto[updaterName] = configUpdater; } } } } }, constructor: function(config) { var me = this, ns = Ext.sparkline; me.canvas = Ext.supports.Canvas ? new ns.CanvasCanvas(me) : new ns.VmlCanvas(me); me.callParent([ config ]); }, 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; }, updateConfigChange: function(newValue) { var me = this; if (me.bufferRedraw || !me.height || !me.width) { me.redrawQueue[me.getId()] = me; if (!me.redrawTimer) { Ext.sparkline.Base.prototype.redrawTimer = Ext.raf(me.processRedrawQueue); } } else { me.redraw(); } return newValue; }, applyTipTpl: function(tipTpl) { if (tipTpl && !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; }, updateWidth: function(width, oldWidth) { var me = this, dom = me.element.dom, measurer = me.measurer; me.callParent([ width, oldWidth ]); me.canvas.setWidth(width); me.width = width; if (me.height == null && measurer) { me.setHeight(parseInt(measurer.getCachedStyle(dom.parentNode, 'line-height'), 10)); } }, updateHeight: function(height, oldHeight) { var me = this; me.callParent([ height, oldHeight ]); me.canvas.setHeight(height); me.height = height; }, setValues: function(values) { var me = this, oldValues = me.getValues(); values = values == null ? [] : Ext.Array.from(values); me.values = values; me.callParent([ values ]); if (values === oldValues) { me.updateValues([ values, oldValues ]); } }, redraw: function() { var me = this; if (!me.destroyed) { me.canvas.onOwnerUpdate(); me.canvas.reset(); if (me.getValues()) { me.onUpdate(); 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) { var me = this; me.canvasRegion = me.canvasRegion || me.canvas.el.getRegion(); me.currentPageXY = e.getPoint(); me.redraw(); }, onMouseLeave: function() { var me = this; me.canvasRegion = me.currentPageXY = me.targetX = me.targetY = null; me.redraw(); me.hideTip(); }, updateDisplay: function() { var me = this, values = me.getValues(), tipHtml, region; if (values && values.length && me.currentPageXY && me.canvasRegion.contains(me.currentPageXY)) { region = me.getRegion(me.currentPageXY[0] - me.canvasRegion.left, (me.canvasRegion.bottom - 1) - me.currentPageXY[1]); if (region != null && me.isValidRegion(region, values)) { if (!me.disableHighlight) { me.renderHighlight(region); } if (!me.getDisableTooltips()) { tipHtml = me.getRegionTooltip(region); } } if (me.hasListeners.sparklineregionchange) { me.fireEvent('sparklineregionchange', me); } if (tipHtml) { me.getSharedTooltip().setHtml(tipHtml); me.showTip(); } } if (!tipHtml) { me.hideTip(); } }, getRegion: Ext.emptyFn, getRegionTooltip: function(region) { var me = this, 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 (entries.length) { return entries.join('
'); } return ''; }, getRegionFields: Ext.emptyFn, calcHighlightColor: function(color) { var me = this, highlightColor = me.getHighlightColor(), lighten = me.getHighlightLighten(), o; if (highlightColor) { return highlightColor; } if (lighten) { o = Ext.util.Color.fromString(color); if (o) { o.lighten(lighten); color = o.toHex(); } } return color; }, destroy: function() { delete this.redrawQueue[this.getId()]; this.callParent(); }, privates: { hideTip: Ext.privateFn, isValidRegion: function(region, values) { return region < values.length; }, showTip: Ext.privateFn } }, function(SparklineBase) { var proto = SparklineBase.prototype; proto.getSharedTooltip = function() { var me = this, tooltip = me.tooltip; if (!tooltip) { proto.tooltip = tooltip = SparklineBase.constructTip(); } return tooltip; }; SparklineBase.onClassCreated(SparklineBase); proto.processRedrawQueue = function() { var redrawQueue = proto.redrawQueue, id; for (id in redrawQueue) { redrawQueue[id].redraw(); } proto.redrawQueue = {}; proto.redrawTimer = 0; }; }); 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, 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: '● {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); } } me.updateConfigChange(); 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; if (values.length) { 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 != null) { 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: [ '{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); if (!this.raw) { newValues.sort(function(a, b) { return a - b; }); } this.disabled = !(newValues && newValues.length); this.updateConfigChange(); 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 { 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.canvasRegion.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: [ '{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); this.updateConfigChange(); 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[parseInt(region.substr(1), 10)], region: region }; }, renderHighlight: function(region) { var me = this, valueShapes = me.valueShapes, shapes = me.shapes, shapeId = valueShapes[region], shape; delete shapes[shapeId]; switch (region.substr(0, 1)) { case 'r': shape = me.renderRange(parseInt(region.substr(1), 10), true); break; case 'p': shape = me.renderPerformance(true); break; case 't': shape = me.renderTarget(true); break; } valueShapes[region] = shape.id; shapes[shape.id] = region; me.canvas.replaceWithShape(shapeId, shape); }, renderRange: function(region, highlight) { var me = this, rangeval = me.values[region], rangewidth = Math.round(me.getWidth() * ((rangeval - me.min) / me.range)), colors = me.getRangeColors(), color = colors[Math.min(region - 2, colors.length - 1)]; if (highlight) { color = me.calcHighlightColor(color); } return me.canvas.drawRect(0, 0, rangewidth - 1, me.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.canvasRegion.contains(me.currentPageXY)) { me.updateDisplay(); } canvas.render(); }, privates: { isValidRegion: function(region, values) { return parseInt(region.substr(1), 10) < values.length; } } }); 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: '{prefix}{value}{suffix}', applyValues: function(newValues) { newValues = Ext.Array.map(Ext.Array.from(newValues), Number); this.disabled = !(newValues && newValues.length); this.updateConfigChange(); 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, alias: 'widget.sparklineline', config: { fillColor: '#def', 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, valueSpots: null }, tipTpl: '● {prefix}{y}{suffix}', applyValueSpots: function(valueSpots) { if (valueSpots && !valueSpots.get) { valueSpots = new Ext.sparkline.RangeMap(valueSpots); } this.updateConfigChange(); 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; for (i = 0; i < valcount; i++) { val = values[i]; if (typeof val === 'string') { val = val.split(':'); } if (val && val.length === 2) { xvalues.push(Number(val[0])); yvalues.push(val = Number(val[1])); yminmax.push(val); } else { xvalues.push(i); if (val == null || val === 'null') { yvalues.push(null); } else { yvalues.push(val = Number(val)); yminmax.push(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.canvasRegion.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: '● {value} ({percent:number("0.0")}%)', applyValues: function(newValues) { newValues = Ext.Array.map(Ext.Array.from(newValues), Number); this.disabled = !(newValues && newValues.length); this.updateConfigChange(); 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.canvasRegion.contains(me.currentPageXY)) { me.currentRegion = null; me.updateDisplay(); } canvas.render(); } }); Ext.define('Ext.sparkline.TriState', { extend: Ext.sparkline.BarBase, alias: 'widget.sparklinetristate', config: { barWidth: 4, barSpacing: 1, posBarColor: '#6f6', negBarColor: '#f44', zeroBarColor: '#999', colorMap: {} }, tipTpl: [ '● {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); } } me.updateConfigChange(); return colorMap; }, applyValues: function(newValues) { newValues = Ext.Array.map(Ext.Array.from(newValues), Number); this.disabled = !(newValues && newValues.length); this.updateConfigChange(); 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.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: '"', lineBreakRe: /\r?\n/g, lastLineBreakRe: /(\r?\n|\r)$/, constructor: function(config) { if (config) { Ext.apply(this, config); } this.parseREs = {}; this.quoteREs = {}; }, decode: function(input, delimiter, quoteChar) { if (!input) { return []; } var me = this, delim = delimiter || me.delimiter, row = [], result = [ row ], quote = quoteChar !== undefined ? quoteChar : me.quote, quoteREs = me.quoteREs, parseREs = me.parseREs, parseRE, dblQuoteRE, arrMatches, strMatchedDelimiter, strMatchedValue; parseRE = quote === me.quote ? parseREs[delim] : null; parseRE = parseRE || new RegExp( "(\\" + delim + "|\\r?\\n|\\r|^)" + "(?:" + (quote === null ? '()' : "\\" + quote + "([^\\" + quote + "]*(?:\\" + quote + "\\" + quote + "[^\\" + quote + "]*)*)\\" + quote + "|") + "([^" + (quote === null ? '' : quote) + delim + "\\r\\n]*))", "gi"); dblQuoteRE = quote === me.quote ? quoteREs[quote] : null; dblQuoteRE = dblQuoteRE || new RegExp('\\' + quote + '\\' + quote, 'g'); input = input.replace(me.lastLineBreakRe, ''); while ((arrMatches = parseRE.exec(input))) { strMatchedDelimiter = arrMatches[1]; if (strMatchedDelimiter.length && strMatchedDelimiter !== delim) { result.push(row = []); } if (!arrMatches.index && arrMatches[0].charAt(0) === delim) { row.push(''); } if (arrMatches[2]) { strMatchedValue = arrMatches[2].replace(dblQuoteRE, quote); } else { strMatchedValue = arrMatches[3]; } row.push(strMatchedValue); } return result; }, encode: function(input, delimiter, quoteChar) { var me = this, delim = delimiter || me.delimiter, dateFormat = me.dateFormat, quote = quoteChar !== undefined ? quoteChar : 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 && quote !== null) { 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.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.ClickRepeater', { alternateClassName: 'Ext.util.TapRepeater', mixins: [ Ext.mixin.Observable ], config: { el: null, target: null, disabled: null }, interval: 20, delay: 250, preventDefault: true, stopDefault: false, timer: 0, handler: null, scope: null, constructor: function(config) { var me = this; if (arguments.length === 2) { me.setEl(config); config = arguments[1]; } me.mixins.observable.constructor.call(this, config); }, destroy: function() { this.setEl(null); this.callParent(); }, privates: { fireClick: function(e) { var me = this; me.fireEvent("click", me, e); Ext.callback(me.handler, me.scope, [ me, e ], 0, me.getTarget()); }, updateDisabled: function(disabled) { var me = this; if (disabled) { me.savedEl = me.getEl(); me.setEl(null); } else if (me.savedEl) { me.setEl(me.savedEl); } }, updateTarget: function(target) { this.setEl(target.el); }, updateEl: function(newEl, oldEl) { var me = this, elListeners; if (oldEl) { oldEl.selectable(); Ext.undefer(me.timer); if (me.pressedCls) { oldEl.removeCls(me.pressedCls); } Ext.getDoc().un('mouseup', me.handleMouseUp, me); me.elListeners = Ext.destroy(me.elListeners); } if (newEl) { newEl.unselectable(); elListeners = { mousedown: me.handleMouseDown, scope: me, destroyable: true }; if (me.preventDefault || me.stopDefault) { elListeners.click = me.eventOptions; } me.elListeners = newEl.on(elListeners); } }, eventOptions: function(e) { if (this.preventDefault) { e.preventDefault(); } if (this.stopDefault) { e.stopEvent(); } }, handleMouseDown: function(e) { var me = this, el = me.getEl(); Ext.undefer(me.timer); if (me.pressedCls) { el.addCls(me.pressedCls); } me.mousedownTime = Ext.now(); if (e.pointerType === 'mouse') { el.on("mouseout", me.handleMouseOut, me); } Ext.getDoc().on("mouseup", me.handleMouseUp, me); me.fireEvent("mousedown", me, e); me.fireClick(e); if (me.accelerate) { me.delay = 400; } me.timer = Ext.defer(me.click, me.delay || me.interval, me, [ e ]); if (me.mousedownPreventDefault) { e.preventDefault(); } if (me.mousedownStopEvent) { e.stopEvent(); } }, click: function(e) { var me = this; me.fireClick(e); me.timer = Ext.defer(me.click, me.accelerate ? me.easeOutExpo(Ext.now() - me.mousedownTime, 400, -390, 12000) : me.interval, me, [ e ]); }, easeOutExpo: function(t, b, c, d) { return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; }, handleMouseOut: function() { var me = this, el = me.getEl(); Ext.undefer(me.timer); if (me.pressedCls) { el.removeCls(me.pressedCls); } el.on("mouseover", me.handleMouseReturn, me); }, handleMouseReturn: function(e) { var me = this, el = me.getEl(); el.un("mouseover", me.handleMouseReturn, me); if (me.pressedCls) { el.addCls(me.pressedCls); } me.click(e); }, handleMouseUp: function(e) { var me = this, el = me.getEl(); Ext.undefer(me.timer); el.un("mouseover", me.handleMouseReturn, me); el.un("mouseout", me.handleMouseOut, me); Ext.getDoc().un("mouseup", me.handleMouseUp, me); if (me.pressedCls) { el.removeCls(me.pressedCls); } me.fireEvent("mouseup", me, e); } } }); Ext.define('Ext.util.Cookies', { singleton: true, set: function(name, value) { var argv = arguments, argc = argv.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.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.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.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.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.callParent(); }, 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.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) { me._timer = Ext.undefer(me._timer); 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.Spans', { isSpans: true, constructor: function() { this.spans = this.spans || []; }, clear: function() { this.spans.length = 0; return this; }, add: function(begin, end) { if (end === undefined) { if (typeof begin === 'number') { end = begin + 1; } else { end = begin[1]; begin = begin[0]; } } var me = this, spans = me.spans, b, e, first, last, span; first = me.bisect(begin); if (first) { span = spans[first - 1]; b = span[0]; e = span[1]; if (begin <= e) { if (end <= e) { return false; } begin = b; spans.splice(--first, 1); } } last = me.bisect(end); if (last > first) { span = spans[last - 1]; end = Math.max(end, span[1]); } if (last < spans.length) { span = spans[last]; if (end === span[0]) { end = span[1]; ++last; } } spans.splice(first, last - first, [ begin, end ]); return true; }, contains: function(begin, end) { if (end === undefined) { if (typeof begin === 'number') { end = begin + 1; } else { end = begin[1]; begin = begin[0]; } } var spans = this.spans, index = this.bisect(begin), ret = false, e, span; if (index && begin < (e = spans[index - 1][1])) { ret = end <= e; } else if (index < spans.length) { span = spans[index]; ret = span[0] <= begin && end <= span[1]; } return ret; }, each: function(fn, scope) { var spans = this.spans, len = spans.length, i, span, j; for (i = 0; i < len; i++) { span = spans[i]; for (j = span[0]; j < span[1]; j++) { if (fn.call(scope || this, i) === false) { return; } } } }, intersects: function(begin, end) { if (end === undefined) { if (typeof begin === 'number') { end = begin + 1; } else { end = begin[1]; begin = begin[0]; } } var spans = this.spans, index = this.bisect(begin), ret = false; if (index && begin < spans[index - 1][1]) { ret = true; } else if (index < spans.length) { ret = spans[index][0] < end; } return ret; }, remove: function(begin, end) { if (end === undefined) { if (typeof begin === 'number') { end = begin + 1; } else { end = begin[1]; begin = begin[0]; } } var me = this, spans = me.spans, first = me.bisect(begin), ret = false, last, span, tmp; if (first) { span = spans[first - 1]; tmp = span[1]; if (begin < tmp) { span[1] = begin; if (end < tmp) { spans.splice(first, 0, [ end, tmp ]); return true; } ret = true; } } last = me.bisect(end); if (first < last) { ret = true; span = spans[last - 1]; if (end < span[1]) { span[0] = end; --last; } last -= first; if (last) { spans.splice(first, last); } } return ret; }, stash: function() { return this.spans.slice(); }, unstash: function(pickle) { this.spans = pickle; return this; }, getCount: function() { var spans = this.spans, len = spans.length, result = 0, i, span; for (i = 0; i < len; i++) { span = spans[i]; result += span[1] - span[0]; } return result; }, privates: { bisect: function(value) { return Ext.Number.bisectTuples(this.spans, value, 0); } } }); Ext.define('Ext.util.TsvDecoder', { extend: Ext.util.DelimitedValue, alternateClassName: 'Ext.util.TSV', delimiter: '\t' }, function(TSVClass) { Ext.util.TSV = new TSVClass(); }); Ext.define('Ext.util.TaskManager', { extend: Ext.util.TaskRunner, alternateClassName: [ 'Ext.TaskManager' ], singleton: true }); Ext.define('Ext.util.TextMetrics', { statics: { shared: null, measure: function(el, text, fixedWidth) { var me = this, shared = me.shared || (me.shared = new me(el, fixedWidth)); shared.bind(el); shared.setFixedWidth(fixedWidth || 'auto'); return shared.getSize(text); }, destroy: function() { this.shared = Ext.destroy(this.shared); } }, constructor: function(bindTo, fixedWidth) { var me = this, measure = me.measure = Ext.getBody().createChild({ 'data-sticky': true, role: 'presentation', cls: Ext.baseCSSPrefix + 'textmetrics', style: { position: 'absolute', left: '-1000px', top: '-1000px', visibility: 'hidden' } }); if (bindTo) { me.bind(bindTo); } 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) { this.measure.setStyle( (this.el || (this.self.prototype.el = new Ext.dom.Fly())).attach(el).getStyle([ 'font-size', 'font-size-adjust', 'font-style', 'font-weight', 'font-family', 'font-kerning', 'font-stretch', 'line-height', 'text-transform', 'text-decoration', '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.el = me.measure = Ext.destroy(me.measure); me.callParent(); } }, 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.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.sizemonitor.OverflowChange', { extend: Ext.util.sizemonitor.Abstract, constructor: function(config) { this.onExpand = this.onExpand.bind(this); this.onShrink = this.onShrink.bind(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 (!(this.destroyed || (Ext.browser.is.Webkit && e.horizontalOverflow && e.verticalOverflow))) { Ext.TaskQueue.requestRead('refresh', this); } }, onShrink: function(e) { if (!(this.destroyed || (Ext.browser.is.Webkit && !e.horizontalOverflow && !e.verticalOverflow))) { Ext.TaskQueue.requestRead('refresh', this); } }, refreshMonitors: function() { if (this.destroying || this.destroyed) { return; } var expandHelper = this.expandHelper, shrinkHelper = this.shrinkHelper, contentBounds = this.getContentBounds(), width = contentBounds.width, height = contentBounds.height, style; if (expandHelper && !expandHelper.destroyed) { style = expandHelper.style; style.width = (width + 1) + 'px'; style.height = (height + 1) + 'px'; } if (shrinkHelper && !shrinkHelper.destroyed) { style = shrinkHelper.style; style.width = width + 'px'; style.height = height + 'px'; } Ext.TaskQueue.requestRead('refresh', this); }, destroy: function() { this.onExpand = this.onShrink = null; this.callParent(); } }); Ext.define('Ext.util.translatable.ScrollParent', { extend: Ext.util.translatable.Dom, alias: 'translatable.scrollparent', 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)); this.callParent([ x, y ]); }, getPosition: function() { var me = this, position = me.position, parent = me.parent; position.x = parent.getScrollLeft(); position.y = parent.getScrollTop(); return position; } }); Ext.ClassManager.addNameAlternateMappings({ "Ext.AbstractComponent": [], "Ext.AbstractManager": [], "Ext.ActionSheet": [], "Ext.Ajax": [], "Ext.Anim": [], "Ext.AnimationQueue": [], "Ext.Audio": [], "Ext.Button": [], "Ext.Component": [ "Ext.lib.Component", "Ext.Gadget" ], "Ext.ComponentManager": [ "Ext.ComponentMgr" ], "Ext.ComponentQuery": [], "Ext.Container": [ "Ext.lib.Container", "Ext.container.Container" ], "Ext.Decorator": [], "Ext.Deferred": [], "Ext.Dialog": [ "Ext.Window", "Ext.window.Window" ], "Ext.Editor": [], "Ext.Evented": [ "Ext.EventedBase" ], "Ext.GlobalEvents": [ "Ext.globalEvents" ], "Ext.Glyph": [], "Ext.Img": [ "Ext.Image" ], "Ext.Indicator": [], "Ext.Label": [], "Ext.LoadMask": [], "Ext.Mask": [], "Ext.Media": [], "Ext.MessageBox": [], "Ext.Mixin": [], "Ext.Panel": [ "Ext.panel.Panel" ], "Ext.Progress": [ "Ext.ProgressBarWidget" ], "Ext.ProgressBase": [], "Ext.Promise": [], "Ext.SegmentedButton": [ "Ext.button.Segmented" ], "Ext.Sheet": [], "Ext.Spacer": [], "Ext.SplitButton": [], "Ext.TaskQueue": [], "Ext.Template": [], "Ext.Title": [], "Ext.TitleBar": [], "Ext.Toast": [], "Ext.Tool": [ "Ext.panel.Tool" ], "Ext.Toolbar": [], "Ext.Video": [], "Ext.Widget": [ "Ext.Gadget" ], "Ext.XTemplate": [], "Ext.app.Application": [], "Ext.app.BaseController": [], "Ext.app.Controller": [], "Ext.app.EventBus": [], "Ext.app.EventDomain": [], "Ext.app.Profile": [], "Ext.app.Util": [], "Ext.app.ViewController": [], "Ext.app.ViewModel": [], "Ext.app.bind.AbstractStub": [], "Ext.app.bind.BaseBinding": [], "Ext.app.bind.Binding": [], "Ext.app.bind.Formula": [], "Ext.app.bind.LinkStub": [], "Ext.app.bind.Multi": [], "Ext.app.bind.Parser": [], "Ext.app.bind.RootStub": [], "Ext.app.bind.Stub": [], "Ext.app.bind.Template": [], "Ext.app.bind.TemplateBinding": [], "Ext.app.domain.Component": [], "Ext.app.domain.Controller": [], "Ext.app.domain.Direct": [], "Ext.app.domain.Global": [], "Ext.app.domain.Store": [], "Ext.app.domain.View": [], "Ext.behavior.Behavior": [], "Ext.carousel.Carousel": [ "Ext.Carousel" ], "Ext.carousel.Infinite": [], "Ext.carousel.Item": [], "Ext.data.AbstractStore": [], "Ext.data.ArrayStore": [ "Ext.data.SimpleStore" ], "Ext.data.Batch": [], "Ext.data.BufferedStore": [], "Ext.data.ChainedStore": [], "Ext.data.Connection": [], "Ext.data.DirectStore": [], "Ext.data.Error": [], "Ext.data.ErrorCollection": [ "Ext.data.Errors" ], "Ext.data.Group": [], "Ext.data.JsonP": [], "Ext.data.JsonPStore": [], "Ext.data.JsonStore": [], "Ext.data.LocalStore": [], "Ext.data.Model": [ "Ext.data.Record" ], "Ext.data.ModelManager": [ "Ext.ModelMgr" ], "Ext.data.NodeInterface": [], "Ext.data.NodeStore": [], "Ext.data.PageMap": [], "Ext.data.ProxyStore": [], "Ext.data.Range": [], "Ext.data.Request": [], "Ext.data.ResultSet": [], "Ext.data.Session": [], "Ext.data.SortTypes": [], "Ext.data.Store": [], "Ext.data.StoreManager": [ "Ext.StoreMgr", "Ext.data.StoreMgr", "Ext.StoreManager" ], "Ext.data.TreeModel": [], "Ext.data.TreeStore": [], "Ext.data.Types": [], "Ext.data.Validation": [], "Ext.data.XmlStore": [], "Ext.data.field.Boolean": [], "Ext.data.field.Date": [], "Ext.data.field.Field": [ "Ext.data.Field" ], "Ext.data.field.Integer": [], "Ext.data.field.Number": [], "Ext.data.field.String": [], "Ext.data.flash.BinaryXhr": [], "Ext.data.identifier.Generator": [], "Ext.data.identifier.Negative": [], "Ext.data.identifier.Sequential": [], "Ext.data.identifier.Uuid": [], "Ext.data.matrix.Matrix": [], "Ext.data.matrix.Side": [], "Ext.data.matrix.Slice": [], "Ext.data.operation.Create": [], "Ext.data.operation.Destroy": [], "Ext.data.operation.Operation": [ "Ext.data.Operation" ], "Ext.data.operation.Read": [], "Ext.data.operation.Update": [], "Ext.data.proxy.Ajax": [ "Ext.data.HttpProxy", "Ext.data.AjaxProxy" ], "Ext.data.proxy.Client": [ "Ext.data.ClientProxy" ], "Ext.data.proxy.Direct": [ "Ext.data.DirectProxy" ], "Ext.data.proxy.JsonP": [ "Ext.data.ScriptTagProxy" ], "Ext.data.proxy.LocalStorage": [ "Ext.data.LocalStorageProxy" ], "Ext.data.proxy.Memory": [ "Ext.data.MemoryProxy" ], "Ext.data.proxy.Proxy": [ "Ext.data.DataProxy", "Ext.data.Proxy" ], "Ext.data.proxy.Rest": [ "Ext.data.RestProxy" ], "Ext.data.proxy.Server": [ "Ext.data.ServerProxy" ], "Ext.data.proxy.SessionStorage": [ "Ext.data.SessionStorageProxy" ], "Ext.data.proxy.WebStorage": [ "Ext.data.WebStorageProxy" ], "Ext.data.reader.Array": [ "Ext.data.ArrayReader" ], "Ext.data.reader.Json": [ "Ext.data.JsonReader" ], "Ext.data.reader.Reader": [ "Ext.data.Reader", "Ext.data.DataReader" ], "Ext.data.reader.Xml": [ "Ext.data.XmlReader" ], "Ext.data.request.Ajax": [], "Ext.data.request.Base": [], "Ext.data.request.Form": [], "Ext.data.schema.Association": [], "Ext.data.schema.ManyToMany": [], "Ext.data.schema.ManyToOne": [], "Ext.data.schema.Namer": [], "Ext.data.schema.OneToOne": [], "Ext.data.schema.Role": [], "Ext.data.schema.Schema": [], "Ext.data.session.BatchVisitor": [], "Ext.data.session.ChangesVisitor": [], "Ext.data.session.ChildChangesVisitor": [], "Ext.data.summary.Average": [], "Ext.data.summary.Base": [], "Ext.data.summary.Count": [], "Ext.data.summary.Max": [], "Ext.data.summary.Min": [], "Ext.data.summary.Sum": [], "Ext.data.validator.AbstractDate": [], "Ext.data.validator.Bound": [], "Ext.data.validator.CIDRv4": [], "Ext.data.validator.CIDRv6": [], "Ext.data.validator.Currency": [], "Ext.data.validator.CurrencyUS": [], "Ext.data.validator.Date": [], "Ext.data.validator.DateTime": [], "Ext.data.validator.Email": [], "Ext.data.validator.Exclusion": [], "Ext.data.validator.Format": [], "Ext.data.validator.IPAddress": [], "Ext.data.validator.Inclusion": [], "Ext.data.validator.Length": [], "Ext.data.validator.List": [], "Ext.data.validator.NotNull": [], "Ext.data.validator.Number": [], "Ext.data.validator.Phone": [], "Ext.data.validator.Presence": [], "Ext.data.validator.Range": [], "Ext.data.validator.Time": [], "Ext.data.validator.Url": [], "Ext.data.validator.Validator": [], "Ext.data.virtual.Group": [], "Ext.data.virtual.Page": [], "Ext.data.virtual.PageMap": [], "Ext.data.virtual.Range": [], "Ext.data.virtual.Store": [], "Ext.data.writer.Json": [ "Ext.data.JsonWriter" ], "Ext.data.writer.Writer": [ "Ext.data.DataWriter", "Ext.data.Writer" ], "Ext.data.writer.Xml": [ "Ext.data.XmlWriter" ], "Ext.dataview.Abstract": [], "Ext.dataview.BoundList": [], "Ext.dataview.BoundListLocation": [], "Ext.dataview.BoundListNavigationModel": [], "Ext.dataview.Component": [], "Ext.dataview.DataItem": [ "Ext.dataview.component.DataItem" ], "Ext.dataview.DataView": [ "Ext.DataView" ], "Ext.dataview.Disclosable": [], "Ext.dataview.EmptyText": [], "Ext.dataview.GenericItem": [], "Ext.dataview.IndexBar": [ "Ext.IndexBar" ], "Ext.dataview.ItemHeader": [], "Ext.dataview.List": [ "Ext.List" ], "Ext.dataview.ListItem": [ "Ext.dataview.component.ListItem" ], "Ext.dataview.Location": [], "Ext.dataview.NavigationModel": [], "Ext.dataview.NestedList": [ "Ext.NestedList" ], "Ext.dataview.Pinnable": [], "Ext.dataview.SimpleListItem": [ "Ext.dataview.component.SimpleListItem" ], "Ext.dataview.listswiper.Accordion": [], "Ext.dataview.listswiper.Item": [], "Ext.dataview.listswiper.ListSwiper": [], "Ext.dataview.listswiper.Stepper": [], "Ext.dataview.plugin.ItemTip": [], "Ext.dataview.plugin.ListPaging": [ "Ext.plugin.ListPaging" ], "Ext.dataview.plugin.SortableList": [ "Ext.plugin.SortableList" ], "Ext.dataview.pullrefresh.Bar": [], "Ext.dataview.pullrefresh.Item": [], "Ext.dataview.pullrefresh.PullRefresh": [ "Ext.plugin.PullRefresh" ], "Ext.dataview.pullrefresh.Spinner": [], "Ext.dataview.selection.Model": [], "Ext.dataview.selection.Records": [], "Ext.dataview.selection.Rows": [], "Ext.dataview.selection.Selection": [], "Ext.direct.Event": [], "Ext.direct.ExceptionEvent": [], "Ext.direct.JsonProvider": [], "Ext.direct.Manager": [], "Ext.direct.PollingProvider": [], "Ext.direct.Provider": [], "Ext.direct.RemotingEvent": [], "Ext.direct.RemotingMethod": [], "Ext.direct.RemotingProvider": [], "Ext.direct.Transaction": [], "Ext.dom.CompositeElement": [ "Ext.CompositeElement" ], "Ext.dom.CompositeElementLite": [ "Ext.CompositeElementLite" ], "Ext.dom.Element": [ "Ext.Element" ], "Ext.dom.ElementEvent": [], "Ext.dom.Fly": [ "Ext.dom.Element.Fly" ], "Ext.dom.GarbageCollector": [], "Ext.dom.Helper": [ "Ext.DomHelper", "Ext.core.DomHelper" ], "Ext.dom.Query": [ "Ext.core.DomQuery", "Ext.DomQuery" ], "Ext.dom.Shadow": [ "Ext.Shadow" ], "Ext.dom.Shim": [], "Ext.dom.TouchAction": [], "Ext.dom.Underlay": [], "Ext.dom.UnderlayPool": [], "Ext.drag.Constraint": [], "Ext.drag.Info": [], "Ext.drag.Item": [], "Ext.drag.Manager": [], "Ext.drag.Source": [], "Ext.drag.Target": [], "Ext.drag.proxy.None": [], "Ext.drag.proxy.Original": [], "Ext.drag.proxy.Placeholder": [], "Ext.event.Event": [ "Ext.EventObjectImpl" ], "Ext.event.gesture.DoubleTap": [], "Ext.event.gesture.Drag": [], "Ext.event.gesture.EdgeSwipe": [], "Ext.event.gesture.LongPress": [], "Ext.event.gesture.MultiTouch": [], "Ext.event.gesture.Pinch": [], "Ext.event.gesture.Recognizer": [], "Ext.event.gesture.Rotate": [], "Ext.event.gesture.SingleTouch": [], "Ext.event.gesture.Swipe": [], "Ext.event.gesture.Tap": [], "Ext.event.publisher.Dom": [], "Ext.event.publisher.ElementPaint": [], "Ext.event.publisher.ElementSize": [], "Ext.event.publisher.Focus": [], "Ext.event.publisher.Gesture": [], "Ext.event.publisher.Publisher": [], "Ext.field.BoxLabelable": [], "Ext.field.Checkbox": [ "Ext.form.Checkbox" ], "Ext.field.ComboBox": [ "Ext.form.field.ComboBox" ], "Ext.field.Container": [], "Ext.field.Date": [ "Ext.form.DatePicker", "Ext.field.DatePicker" ], "Ext.field.DatePickerNative": [ "Ext.form.DatePickerNative" ], "Ext.field.Display": [ "Ext.form.Display" ], "Ext.field.Email": [ "Ext.form.Email" ], "Ext.field.Field": [ "Ext.form.Field" ], "Ext.field.File": [], "Ext.field.FileButton": [], "Ext.field.Hidden": [ "Ext.form.Hidden" ], "Ext.field.Input": [], "Ext.field.InputMask": [], "Ext.field.Manager": [], "Ext.field.Number": [ "Ext.form.Number" ], "Ext.field.Panel": [], "Ext.field.Password": [ "Ext.form.Password" ], "Ext.field.Picker": [], "Ext.field.Radio": [ "Ext.form.Radio" ], "Ext.field.Search": [ "Ext.form.Search" ], "Ext.field.Select": [ "Ext.form.Select" ], "Ext.field.SingleSlider": [], "Ext.field.Slider": [ "Ext.form.Slider" ], "Ext.field.Spinner": [ "Ext.form.Spinner" ], "Ext.field.Text": [ "Ext.form.Text" ], "Ext.field.TextArea": [ "Ext.form.TextArea" ], "Ext.field.Time": [], "Ext.field.Toggle": [ "Ext.form.Toggle" ], "Ext.field.Url": [ "Ext.form.Url" ], "Ext.field.trigger.Base": [], "Ext.field.trigger.Clear": [], "Ext.field.trigger.Component": [], "Ext.field.trigger.Date": [], "Ext.field.trigger.Expand": [], "Ext.field.trigger.File": [], "Ext.field.trigger.Menu": [], "Ext.field.trigger.Reveal": [], "Ext.field.trigger.Search": [], "Ext.field.trigger.SpinDown": [], "Ext.field.trigger.SpinUp": [], "Ext.field.trigger.Time": [], "Ext.field.trigger.Trigger": [], "Ext.form.Borders": [], "Ext.form.FieldSet": [], "Ext.form.Panel": [ "Ext.form.FormPanel" ], "Ext.fx.Animation": [], "Ext.fx.Runner": [], "Ext.fx.State": [], "Ext.fx.animation.Abstract": [], "Ext.fx.animation.Cube": [], "Ext.fx.animation.Fade": [ "Ext.fx.animation.FadeIn" ], "Ext.fx.animation.FadeOut": [], "Ext.fx.animation.Flip": [], "Ext.fx.animation.Pop": [ "Ext.fx.animation.PopIn" ], "Ext.fx.animation.PopOut": [], "Ext.fx.animation.Slide": [ "Ext.fx.animation.SlideIn" ], "Ext.fx.animation.SlideOut": [], "Ext.fx.animation.Wipe": [ "Ext.fx.animation.WipeIn" ], "Ext.fx.animation.WipeOut": [], "Ext.fx.easing.Abstract": [], "Ext.fx.easing.Bounce": [], "Ext.fx.easing.BoundMomentum": [], "Ext.fx.easing.EaseIn": [], "Ext.fx.easing.EaseOut": [], "Ext.fx.easing.Easing": [], "Ext.fx.easing.Linear": [], "Ext.fx.easing.Momentum": [], "Ext.fx.runner.Css": [], "Ext.fx.runner.CssAnimation": [], "Ext.fx.runner.CssTransition": [ "Ext.Animator" ], "Ext.grid.CellEditor": [], "Ext.grid.Grid": [], "Ext.grid.HeaderContainer": [], "Ext.grid.Location": [], "Ext.grid.NavigationModel": [], "Ext.grid.PagingToolbar": [], "Ext.grid.Row": [], "Ext.grid.RowBody": [], "Ext.grid.RowHeader": [], "Ext.grid.SummaryRow": [], "Ext.grid.Tree": [ "Ext.tree.Tree" ], "Ext.grid.cell.Base": [], "Ext.grid.cell.Boolean": [], "Ext.grid.cell.Cell": [], "Ext.grid.cell.Check": [], "Ext.grid.cell.Date": [], "Ext.grid.cell.Expander": [], "Ext.grid.cell.Number": [], "Ext.grid.cell.RowNumberer": [], "Ext.grid.cell.Text": [], "Ext.grid.cell.Tree": [], "Ext.grid.cell.Widget": [], "Ext.grid.column.Boolean": [], "Ext.grid.column.Check": [], "Ext.grid.column.Column": [ "Ext.grid.column.Template" ], "Ext.grid.column.Date": [], "Ext.grid.column.Number": [], "Ext.grid.column.RowNumberer": [], "Ext.grid.column.Selection": [], "Ext.grid.column.Text": [], "Ext.grid.column.Tree": [], "Ext.grid.menu.Columns": [], "Ext.grid.menu.GroupByThis": [], "Ext.grid.menu.ShowInGroups": [], "Ext.grid.menu.SortAsc": [], "Ext.grid.menu.SortDesc": [], "Ext.grid.plugin.CellEditing": [], "Ext.grid.plugin.Clipboard": [], "Ext.grid.plugin.ColumnResizing": [], "Ext.grid.plugin.Editable": [], "Ext.grid.plugin.PagingToolbar": [], "Ext.grid.plugin.RowExpander": [], "Ext.grid.plugin.RowOperations": [ "Ext.grid.plugin.MultiSelection" ], "Ext.grid.plugin.Summary": [ "Ext.grid.plugin.SummaryRow" ], "Ext.grid.plugin.ViewOptions": [], "Ext.grid.plugin.ViewOptionsListItem": [], "Ext.grid.selection.Cells": [], "Ext.grid.selection.Columns": [], "Ext.grid.selection.Model": [], "Ext.grid.selection.Replicator": [], "Ext.grid.selection.SelectionExtender": [], "Ext.layout.Auto": [ "Ext.layout.Default" ], "Ext.layout.Box": [], "Ext.layout.Card": [], "Ext.layout.Carousel": [], "Ext.layout.Center": [], "Ext.layout.Fit": [], "Ext.layout.Float": [], "Ext.layout.Form": [], "Ext.layout.HBox": [], "Ext.layout.VBox": [], "Ext.layout.card.fx.Abstract": [], "Ext.layout.card.fx.Cover": [], "Ext.layout.card.fx.Cube": [], "Ext.layout.card.fx.Fade": [], "Ext.layout.card.fx.Flip": [], "Ext.layout.card.fx.Pop": [], "Ext.layout.card.fx.Reveal": [], "Ext.layout.card.fx.Scroll": [], "Ext.layout.card.fx.ScrollCover": [], "Ext.layout.card.fx.ScrollReveal": [], "Ext.layout.card.fx.Serial": [], "Ext.layout.card.fx.Slide": [], "Ext.layout.card.fx.Style": [], "Ext.layout.overflow.Scroller": [], "Ext.layout.wrapper.BoxDock": [], "Ext.layout.wrapper.Inner": [], "Ext.list.AbstractTreeItem": [], "Ext.list.Location": [], "Ext.list.RootTreeItem": [], "Ext.list.Tree": [], "Ext.list.TreeItem": [], "Ext.menu.CheckItem": [], "Ext.menu.Item": [ "Ext.menu.TextItem" ], "Ext.menu.Manager": [ "Ext.menu.MenuMgr" ], "Ext.menu.Menu": [], "Ext.menu.RadioItem": [], "Ext.menu.Separator": [], "Ext.mixin.Accessible": [], "Ext.mixin.Bindable": [], "Ext.mixin.Bufferable": [], "Ext.mixin.ComponentDelegation": [], "Ext.mixin.ConfigProxy": [], "Ext.mixin.ConfigState": [], "Ext.mixin.Container": [], "Ext.mixin.Dirty": [], "Ext.mixin.Factoryable": [], "Ext.mixin.Focusable": [], "Ext.mixin.FocusableContainer": [], "Ext.mixin.Hookable": [], "Ext.mixin.Inheritable": [], "Ext.mixin.ItemRippler": [], "Ext.mixin.Keyboard": [], "Ext.mixin.Mashup": [], "Ext.mixin.Pluggable": [], "Ext.mixin.Progressable": [], "Ext.mixin.Queryable": [], "Ext.mixin.Responsive": [], "Ext.mixin.Selectable": [], "Ext.mixin.StoreWatcher": [], "Ext.mixin.StyleCacher": [], "Ext.mixin.Templatable": [], "Ext.mixin.Toolable": [], "Ext.mixin.Traversable": [], "Ext.navigation.Bar": [], "Ext.navigation.View": [ "Ext.NavigationView" ], "Ext.override.sparkline.Base": [], "Ext.overrides.Progress": [], "Ext.overrides.Widget": [], "Ext.overrides.app.Application": [], "Ext.overrides.dom.Element": [], "Ext.overrides.drag.proxy.Placeholder": [], "Ext.overrides.list.Tree": [], "Ext.overrides.list.TreeItem": [], "Ext.panel.Collapser": [], "Ext.panel.Collapsible": [], "Ext.panel.Date": [], "Ext.panel.DateTitle": [], "Ext.panel.DateView": [], "Ext.panel.Header": [], "Ext.panel.Resizable": [], "Ext.panel.Resizer": [], "Ext.panel.Time": [], "Ext.panel.TimeHeader": [], "Ext.panel.TimeView": [], "Ext.panel.Title": [], "Ext.panel.YearPicker": [], "Ext.parse.Parser": [], "Ext.parse.Symbol": [], "Ext.parse.Tokenizer": [], "Ext.parse.symbol.Constant": [], "Ext.parse.symbol.Infix": [], "Ext.parse.symbol.InfixRight": [], "Ext.parse.symbol.Paren": [], "Ext.parse.symbol.Prefix": [], "Ext.perf.Accumulator": [], "Ext.perf.Monitor": [ "Ext.Perf" ], "Ext.picker.Date": [ "Ext.DatePicker" ], "Ext.picker.Picker": [ "Ext.Picker" ], "Ext.picker.Slot": [], "Ext.picker.Tablet": [], "Ext.plugin.Abstract": [ "Ext.AbstractPlugin" ], "Ext.plugin.AbstractClipboard": [], "Ext.plugin.MouseEnter": [], "Ext.plugin.Responsive": [], "Ext.plugin.TabGuard": [], "Ext.promise.Consequence": [], "Ext.promise.Deferred": [], "Ext.promise.Promise": [], "Ext.route.Action": [], "Ext.route.Handler": [], "Ext.route.Mixin": [], "Ext.route.Route": [], "Ext.route.Router": [], "Ext.scroll.Scroller": [], "Ext.slider.Slider": [], "Ext.slider.Thumb": [], "Ext.slider.Toggle": [], "Ext.sparkline.Bar": [], "Ext.sparkline.BarBase": [], "Ext.sparkline.Base": [], "Ext.sparkline.Box": [], "Ext.sparkline.Bullet": [], "Ext.sparkline.CanvasBase": [], "Ext.sparkline.CanvasCanvas": [], "Ext.sparkline.Discrete": [], "Ext.sparkline.Line": [], "Ext.sparkline.Pie": [], "Ext.sparkline.RangeMap": [], "Ext.sparkline.Shape": [], "Ext.sparkline.TriState": [], "Ext.sparkline.VmlCanvas": [], "Ext.tab.Bar": [ "Ext.TabBar" ], "Ext.tab.Panel": [ "Ext.TabPanel" ], "Ext.tab.Tab": [ "Ext.Tab" ], "Ext.tip.Manager": [], "Ext.tip.ToolTip": [], "Ext.util.AbstractMixedCollection": [], "Ext.util.Audio": [], "Ext.util.Bag": [], "Ext.util.Base64": [], "Ext.util.BufferedCollection": [], "Ext.util.CSS": [], "Ext.util.CSV": [], "Ext.util.ClickRepeater": [ "Ext.util.TapRepeater" ], "Ext.util.Collection": [], "Ext.util.CollectionKey": [], "Ext.util.Color": [ "Ext.draw.Color" ], "Ext.util.Cookies": [], "Ext.util.DelimitedValue": [], "Ext.util.Draggable": [], "Ext.util.Filter": [], "Ext.util.FilterCollection": [], "Ext.util.Fly": [], "Ext.util.Format": [], "Ext.util.Geolocation": [ "Ext.util.GeoLocation" ], "Ext.util.Group": [], "Ext.util.GroupCollection": [], "Ext.util.Grouper": [], "Ext.util.HashMap": [], "Ext.util.History": [ "Ext.History" ], "Ext.util.Inflector": [], "Ext.util.InputBlocker": [], "Ext.util.ItemCollection": [ "Ext.ItemCollection" ], "Ext.util.KeyMap": [ "Ext.KeyMap" ], "Ext.util.KeyNav": [ "Ext.KeyNav" ], "Ext.util.LineSegment": [], "Ext.util.LocalStorage": [], "Ext.util.LruCache": [], "Ext.util.MixedCollection": [], "Ext.util.ObjectTemplate": [], "Ext.util.Observable": [], "Ext.util.Offset": [], "Ext.util.PaintMonitor": [], "Ext.util.Point": [], "Ext.util.PositionMap": [], "Ext.util.Positionable": [], "Ext.util.Region": [], "Ext.util.Schedulable": [], "Ext.util.Scheduler": [], "Ext.util.SizeMonitor": [], "Ext.util.Sortable": [], "Ext.util.Sorter": [], "Ext.util.SorterCollection": [], "Ext.util.Spans": [], "Ext.util.TextMetrics": [], "Ext.util.TranslatableGroup": [], "Ext.util.TranslatableList": [], "Ext.util.TsvDecoder": [ "Ext.util.TSV" ], "Ext.util.Wrapper": [], "Ext.util.XTemplateCompiler": [], "Ext.util.XTemplateParser": [], "Ext.util.paintmonitor.Abstract": [], "Ext.util.paintmonitor.CssAnimation": [], "Ext.util.paintmonitor.OverflowChange": [], "Ext.util.sizemonitor.Abstract": [], "Ext.util.sizemonitor.OverflowChange": [], "Ext.util.sizemonitor.Scroll": [], "Ext.util.translatable.Abstract": [], "Ext.util.translatable.Component": [], "Ext.util.translatable.CssPosition": [], "Ext.util.translatable.CssTransform": [], "Ext.util.translatable.Dom": [], "Ext.util.translatable.ScrollParent": [], "Ext.util.translatable.ScrollPosition": [], "Ext.viewport.Android": [], "Ext.viewport.Default": [], "Ext.viewport.Ios": [], "Ext.viewport.Viewport": [], "Ext.viewport.WindowsPhone": [ "Ext.viewport.WP" ] }); Ext.ClassManager.addNameAliasMappings({ "Ext.AbstractComponent": [], "Ext.AbstractManager": [], "Ext.ActionSheet": [ "widget.actionsheet" ], "Ext.Ajax": [], "Ext.Anim": [], "Ext.AnimationQueue": [], "Ext.Audio": [ "widget.audio" ], "Ext.Button": [ "widget.button" ], "Ext.Component": [ "widget.component" ], "Ext.ComponentManager": [], "Ext.ComponentQuery": [], "Ext.Container": [ "widget.container" ], "Ext.Decorator": [], "Ext.Deferred": [], "Ext.Dialog": [ "widget.dialog", "widget.window" ], "Ext.Editor": [ "widget.editor" ], "Ext.Evented": [], "Ext.GlobalEvents": [], "Ext.Glyph": [], "Ext.Img": [ "widget.image", "widget.img" ], "Ext.Indicator": [ "widget.indicator" ], "Ext.Label": [ "widget.label" ], "Ext.LoadMask": [ "widget.loadmask" ], "Ext.Mask": [ "widget.mask" ], "Ext.Media": [ "widget.media" ], "Ext.MessageBox": [ "widget.messagebox" ], "Ext.Mixin": [], "Ext.Panel": [ "widget.panel" ], "Ext.Progress": [ "widget.progress", "widget.progressbarwidget" ], "Ext.ProgressBase": [], "Ext.Promise": [], "Ext.SegmentedButton": [ "widget.segmentedbutton" ], "Ext.Sheet": [ "widget.sheet" ], "Ext.Spacer": [ "widget.spacer" ], "Ext.SplitButton": [ "widget.splitbutton" ], "Ext.TaskQueue": [], "Ext.Template": [], "Ext.Title": [ "widget.title" ], "Ext.TitleBar": [ "widget.titlebar" ], "Ext.Toast": [], "Ext.Tool": [ "widget.paneltool", "widget.tool" ], "Ext.Toolbar": [ "widget.toolbar" ], "Ext.Video": [ "widget.video" ], "Ext.Widget": [ "widget.widget" ], "Ext.XTemplate": [], "Ext.app.Application": [], "Ext.app.BaseController": [], "Ext.app.Controller": [], "Ext.app.EventBus": [], "Ext.app.EventDomain": [], "Ext.app.Profile": [], "Ext.app.Util": [], "Ext.app.ViewController": [ "controller.controller" ], "Ext.app.ViewModel": [ "viewmodel.default" ], "Ext.app.bind.AbstractStub": [], "Ext.app.bind.BaseBinding": [], "Ext.app.bind.Binding": [], "Ext.app.bind.Formula": [], "Ext.app.bind.LinkStub": [], "Ext.app.bind.Multi": [], "Ext.app.bind.Parser": [], "Ext.app.bind.RootStub": [], "Ext.app.bind.Stub": [], "Ext.app.bind.Template": [], "Ext.app.bind.TemplateBinding": [], "Ext.app.domain.Component": [], "Ext.app.domain.Controller": [], "Ext.app.domain.Direct": [], "Ext.app.domain.Global": [], "Ext.app.domain.Store": [], "Ext.app.domain.View": [], "Ext.behavior.Behavior": [], "Ext.carousel.Carousel": [ "widget.carousel" ], "Ext.carousel.Infinite": [], "Ext.carousel.Item": [], "Ext.data.AbstractStore": [], "Ext.data.ArrayStore": [ "store.array" ], "Ext.data.Batch": [], "Ext.data.BufferedStore": [ "store.buffered" ], "Ext.data.ChainedStore": [ "store.chained" ], "Ext.data.Connection": [], "Ext.data.DirectStore": [ "store.direct" ], "Ext.data.Error": [], "Ext.data.ErrorCollection": [], "Ext.data.Group": [], "Ext.data.JsonP": [], "Ext.data.JsonPStore": [ "store.jsonp" ], "Ext.data.JsonStore": [ "store.json" ], "Ext.data.LocalStore": [], "Ext.data.Model": [], "Ext.data.ModelManager": [], "Ext.data.NodeInterface": [], "Ext.data.NodeStore": [ "store.node" ], "Ext.data.PageMap": [], "Ext.data.ProxyStore": [], "Ext.data.Range": [], "Ext.data.Request": [], "Ext.data.ResultSet": [], "Ext.data.Session": [], "Ext.data.SortTypes": [], "Ext.data.Store": [ "store.store" ], "Ext.data.StoreManager": [], "Ext.data.TreeModel": [], "Ext.data.TreeStore": [ "store.tree" ], "Ext.data.Types": [], "Ext.data.Validation": [], "Ext.data.XmlStore": [ "store.xml" ], "Ext.data.field.Boolean": [ "data.field.bool", "data.field.boolean" ], "Ext.data.field.Date": [ "data.field.date" ], "Ext.data.field.Field": [ "data.field.auto" ], "Ext.data.field.Integer": [ "data.field.int", "data.field.integer" ], "Ext.data.field.Number": [ "data.field.float", "data.field.number" ], "Ext.data.field.String": [ "data.field.string" ], "Ext.data.flash.BinaryXhr": [], "Ext.data.identifier.Generator": [ "data.identifier.default" ], "Ext.data.identifier.Negative": [ "data.identifier.negative" ], "Ext.data.identifier.Sequential": [ "data.identifier.sequential" ], "Ext.data.identifier.Uuid": [ "data.identifier.uuid" ], "Ext.data.matrix.Matrix": [], "Ext.data.matrix.Side": [], "Ext.data.matrix.Slice": [], "Ext.data.operation.Create": [ "data.operation.create" ], "Ext.data.operation.Destroy": [ "data.operation.destroy" ], "Ext.data.operation.Operation": [], "Ext.data.operation.Read": [ "data.operation.read" ], "Ext.data.operation.Update": [ "data.operation.update" ], "Ext.data.proxy.Ajax": [ "proxy.ajax" ], "Ext.data.proxy.Client": [], "Ext.data.proxy.Direct": [ "proxy.direct" ], "Ext.data.proxy.JsonP": [ "proxy.jsonp", "proxy.scripttag" ], "Ext.data.proxy.LocalStorage": [ "proxy.localstorage" ], "Ext.data.proxy.Memory": [ "proxy.memory" ], "Ext.data.proxy.Proxy": [ "proxy.proxy" ], "Ext.data.proxy.Rest": [ "proxy.rest" ], "Ext.data.proxy.Server": [ "proxy.server" ], "Ext.data.proxy.SessionStorage": [ "proxy.sessionstorage" ], "Ext.data.proxy.WebStorage": [], "Ext.data.reader.Array": [ "reader.array" ], "Ext.data.reader.Json": [ "reader.json" ], "Ext.data.reader.Reader": [ "reader.base" ], "Ext.data.reader.Xml": [ "reader.xml" ], "Ext.data.request.Ajax": [ "request.ajax" ], "Ext.data.request.Base": [], "Ext.data.request.Form": [ "request.form" ], "Ext.data.schema.Association": [], "Ext.data.schema.ManyToMany": [], "Ext.data.schema.ManyToOne": [], "Ext.data.schema.Namer": [ "namer.default" ], "Ext.data.schema.OneToOne": [], "Ext.data.schema.Role": [], "Ext.data.schema.Schema": [ "schema.default" ], "Ext.data.session.BatchVisitor": [], "Ext.data.session.ChangesVisitor": [], "Ext.data.session.ChildChangesVisitor": [], "Ext.data.summary.Average": [ "data.summary.average" ], "Ext.data.summary.Base": [ "data.summary.base" ], "Ext.data.summary.Count": [ "data.summary.count" ], "Ext.data.summary.Max": [ "data.summary.max" ], "Ext.data.summary.Min": [ "data.summary.min" ], "Ext.data.summary.Sum": [ "data.summary.sum" ], "Ext.data.validator.AbstractDate": [], "Ext.data.validator.Bound": [ "data.validator.bound" ], "Ext.data.validator.CIDRv4": [ "data.validator.cidrv4" ], "Ext.data.validator.CIDRv6": [ "data.validator.cidrv6" ], "Ext.data.validator.Currency": [ "data.validator.currency" ], "Ext.data.validator.CurrencyUS": [ "data.validator.currency-us" ], "Ext.data.validator.Date": [ "data.validator.date" ], "Ext.data.validator.DateTime": [ "data.validator.datetime" ], "Ext.data.validator.Email": [ "data.validator.email" ], "Ext.data.validator.Exclusion": [ "data.validator.exclusion" ], "Ext.data.validator.Format": [ "data.validator.format" ], "Ext.data.validator.IPAddress": [ "data.validator.ipaddress" ], "Ext.data.validator.Inclusion": [ "data.validator.inclusion" ], "Ext.data.validator.Length": [ "data.validator.length" ], "Ext.data.validator.List": [ "data.validator.list" ], "Ext.data.validator.NotNull": [ "data.validator.notnull" ], "Ext.data.validator.Number": [ "data.validator.number" ], "Ext.data.validator.Phone": [ "data.validator.phone" ], "Ext.data.validator.Presence": [ "data.validator.presence" ], "Ext.data.validator.Range": [ "data.validator.range" ], "Ext.data.validator.Time": [ "data.validator.time" ], "Ext.data.validator.Url": [ "data.validator.url" ], "Ext.data.validator.Validator": [ "data.validator.base" ], "Ext.data.virtual.Group": [], "Ext.data.virtual.Page": [], "Ext.data.virtual.PageMap": [], "Ext.data.virtual.Range": [], "Ext.data.virtual.Store": [ "store.virtual" ], "Ext.data.writer.Json": [ "writer.json" ], "Ext.data.writer.Writer": [ "writer.base" ], "Ext.data.writer.Xml": [ "writer.xml" ], "Ext.dataview.Abstract": [], "Ext.dataview.BoundList": [ "widget.boundlist" ], "Ext.dataview.BoundListLocation": [], "Ext.dataview.BoundListNavigationModel": [ "navmodel.boundlist" ], "Ext.dataview.Component": [ "widget.componentdataview" ], "Ext.dataview.DataItem": [ "widget.dataitem" ], "Ext.dataview.DataView": [ "widget.dataview" ], "Ext.dataview.Disclosable": [], "Ext.dataview.EmptyText": [ "widget.emptytext" ], "Ext.dataview.GenericItem": [], "Ext.dataview.IndexBar": [ "widget.indexbar" ], "Ext.dataview.ItemHeader": [ "widget.itemheader" ], "Ext.dataview.List": [ "widget.list" ], "Ext.dataview.ListItem": [ "widget.listitem" ], "Ext.dataview.Location": [], "Ext.dataview.NavigationModel": [ "navmodel.dataview" ], "Ext.dataview.NestedList": [ "widget.nestedlist" ], "Ext.dataview.Pinnable": [], "Ext.dataview.SimpleListItem": [ "widget.simplelistitem" ], "Ext.dataview.listswiper.Accordion": [ "widget.listswiperaccordion" ], "Ext.dataview.listswiper.Item": [ "widget.listswiperitem" ], "Ext.dataview.listswiper.ListSwiper": [ "plugin.listswiper" ], "Ext.dataview.listswiper.Stepper": [ "widget.listswiperstepper" ], "Ext.dataview.plugin.ItemTip": [ "plugin.dataviewtip" ], "Ext.dataview.plugin.ListPaging": [ "plugin.listpaging" ], "Ext.dataview.plugin.SortableList": [ "plugin.sortablelist" ], "Ext.dataview.pullrefresh.Bar": [ "widget.pullrefreshbar" ], "Ext.dataview.pullrefresh.Item": [], "Ext.dataview.pullrefresh.PullRefresh": [ "plugin.pullrefresh" ], "Ext.dataview.pullrefresh.Spinner": [ "widget.pullrefreshspinner" ], "Ext.dataview.selection.Model": [ "selmodel.dataview" ], "Ext.dataview.selection.Records": [ "selection.records" ], "Ext.dataview.selection.Rows": [ "selection.rows" ], "Ext.dataview.selection.Selection": [], "Ext.direct.Event": [ "direct.event" ], "Ext.direct.ExceptionEvent": [ "direct.exception" ], "Ext.direct.JsonProvider": [ "direct.jsonprovider" ], "Ext.direct.Manager": [], "Ext.direct.PollingProvider": [ "direct.pollingprovider" ], "Ext.direct.Provider": [ "direct.provider" ], "Ext.direct.RemotingEvent": [ "direct.rpc" ], "Ext.direct.RemotingMethod": [], "Ext.direct.RemotingProvider": [ "direct.remotingprovider" ], "Ext.direct.Transaction": [ "direct.transaction" ], "Ext.dom.CompositeElement": [], "Ext.dom.CompositeElementLite": [], "Ext.dom.Element": [], "Ext.dom.ElementEvent": [], "Ext.dom.Fly": [], "Ext.dom.GarbageCollector": [], "Ext.dom.Helper": [], "Ext.dom.Query": [], "Ext.dom.Shadow": [], "Ext.dom.Shim": [], "Ext.dom.TouchAction": [], "Ext.dom.Underlay": [], "Ext.dom.UnderlayPool": [], "Ext.drag.Constraint": [ "drag.constraint.base" ], "Ext.drag.Info": [], "Ext.drag.Item": [], "Ext.drag.Manager": [], "Ext.drag.Source": [], "Ext.drag.Target": [], "Ext.drag.proxy.None": [ "drag.proxy.none" ], "Ext.drag.proxy.Original": [ "drag.proxy.original" ], "Ext.drag.proxy.Placeholder": [ "drag.proxy.placeholder" ], "Ext.event.Event": [], "Ext.event.gesture.DoubleTap": [], "Ext.event.gesture.Drag": [], "Ext.event.gesture.EdgeSwipe": [], "Ext.event.gesture.LongPress": [], "Ext.event.gesture.MultiTouch": [], "Ext.event.gesture.Pinch": [], "Ext.event.gesture.Recognizer": [], "Ext.event.gesture.Rotate": [], "Ext.event.gesture.SingleTouch": [], "Ext.event.gesture.Swipe": [], "Ext.event.gesture.Tap": [], "Ext.event.publisher.Dom": [], "Ext.event.publisher.ElementPaint": [], "Ext.event.publisher.ElementSize": [], "Ext.event.publisher.Focus": [], "Ext.event.publisher.Gesture": [], "Ext.event.publisher.Publisher": [], "Ext.field.BoxLabelable": [], "Ext.field.Checkbox": [ "widget.checkbox", "widget.checkboxfield" ], "Ext.field.ComboBox": [ "widget.combobox", "widget.comboboxfield" ], "Ext.field.Container": [ "widget.containerfield", "widget.fieldcontainer" ], "Ext.field.Date": [ "widget.datefield", "widget.datepickerfield" ], "Ext.field.DatePickerNative": [ "widget.datepickernativefield" ], "Ext.field.Display": [ "widget.displayfield" ], "Ext.field.Email": [ "widget.emailfield" ], "Ext.field.Field": [ "widget.field" ], "Ext.field.File": [ "widget.filefield" ], "Ext.field.FileButton": [ "widget.filebutton" ], "Ext.field.Hidden": [ "widget.hiddenfield" ], "Ext.field.Input": [ "widget.inputfield" ], "Ext.field.InputMask": [], "Ext.field.Manager": [], "Ext.field.Number": [ "widget.numberfield" ], "Ext.field.Panel": [ "widget.fieldpanel" ], "Ext.field.Password": [ "widget.passwordfield" ], "Ext.field.Picker": [ "widget.pickerfield" ], "Ext.field.Radio": [ "widget.radio", "widget.radiofield" ], "Ext.field.Search": [ "widget.searchfield" ], "Ext.field.Select": [ "widget.selectfield" ], "Ext.field.SingleSlider": [ "widget.singlesliderfield" ], "Ext.field.Slider": [ "widget.sliderfield" ], "Ext.field.Spinner": [ "widget.spinnerfield" ], "Ext.field.Text": [ "widget.textfield" ], "Ext.field.TextArea": [ "widget.textareafield" ], "Ext.field.Time": [ "widget.timefield" ], "Ext.field.Toggle": [ "widget.togglefield" ], "Ext.field.Url": [ "widget.urlfield" ], "Ext.field.trigger.Base": [ "trigger.base" ], "Ext.field.trigger.Clear": [ "trigger.clear", "widget.cleartrigger" ], "Ext.field.trigger.Component": [ "trigger.component" ], "Ext.field.trigger.Date": [ "trigger.date", "widget.datetrigger" ], "Ext.field.trigger.Expand": [ "trigger.expand", "widget.expandtrigger" ], "Ext.field.trigger.File": [ "trigger.file" ], "Ext.field.trigger.Menu": [ "trigger.menu", "widget.menutrigger" ], "Ext.field.trigger.Reveal": [ "trigger.reveal", "widget.revealtrigger" ], "Ext.field.trigger.Search": [ "trigger.search", "widget.searchtrigger" ], "Ext.field.trigger.SpinDown": [ "trigger.spindown", "widget.spindowntrigger" ], "Ext.field.trigger.SpinUp": [ "trigger.spinup", "widget.spinuptrigger" ], "Ext.field.trigger.Time": [ "trigger.time", "widget.timetrigger" ], "Ext.field.trigger.Trigger": [ "trigger.trigger", "widget.trigger" ], "Ext.form.Borders": [], "Ext.form.FieldSet": [ "widget.fieldset" ], "Ext.form.Panel": [ "widget.formpanel" ], "Ext.fx.Animation": [], "Ext.fx.Runner": [], "Ext.fx.State": [], "Ext.fx.animation.Abstract": [], "Ext.fx.animation.Cube": [ "animation.cube" ], "Ext.fx.animation.Fade": [ "animation.fade", "animation.fadeIn" ], "Ext.fx.animation.FadeOut": [ "animation.fadeOut" ], "Ext.fx.animation.Flip": [ "animation.flip" ], "Ext.fx.animation.Pop": [ "animation.pop", "animation.popIn" ], "Ext.fx.animation.PopOut": [ "animation.popOut" ], "Ext.fx.animation.Slide": [ "animation.slide", "animation.slideIn" ], "Ext.fx.animation.SlideOut": [ "animation.slideOut" ], "Ext.fx.animation.Wipe": [], "Ext.fx.animation.WipeOut": [], "Ext.fx.easing.Abstract": [], "Ext.fx.easing.Bounce": [], "Ext.fx.easing.BoundMomentum": [], "Ext.fx.easing.EaseIn": [ "easing.ease-in" ], "Ext.fx.easing.EaseOut": [ "easing.ease-out" ], "Ext.fx.easing.Easing": [], "Ext.fx.easing.Linear": [ "easing.linear" ], "Ext.fx.easing.Momentum": [], "Ext.fx.runner.Css": [], "Ext.fx.runner.CssAnimation": [], "Ext.fx.runner.CssTransition": [], "Ext.grid.CellEditor": [ "widget.celleditor" ], "Ext.grid.Grid": [ "widget.grid" ], "Ext.grid.HeaderContainer": [ "widget.headercontainer" ], "Ext.grid.Location": [], "Ext.grid.NavigationModel": [ "navmodel.grid" ], "Ext.grid.PagingToolbar": [ "widget.pagingtoolbar" ], "Ext.grid.Row": [ "widget.gridrow" ], "Ext.grid.RowBody": [ "widget.rowbody" ], "Ext.grid.RowHeader": [ "widget.rowheader" ], "Ext.grid.SummaryRow": [ "widget.gridsummaryrow" ], "Ext.grid.Tree": [ "widget.tree" ], "Ext.grid.cell.Base": [ "widget.gridcellbase" ], "Ext.grid.cell.Boolean": [ "widget.booleancell" ], "Ext.grid.cell.Cell": [ "widget.gridcell" ], "Ext.grid.cell.Check": [ "widget.checkcell" ], "Ext.grid.cell.Date": [ "widget.datecell" ], "Ext.grid.cell.Expander": [ "widget.expandercell" ], "Ext.grid.cell.Number": [ "widget.numbercell" ], "Ext.grid.cell.RowNumberer": [ "widget.rownumberercell" ], "Ext.grid.cell.Text": [ "widget.textcell" ], "Ext.grid.cell.Tree": [ "widget.treecell" ], "Ext.grid.cell.Widget": [ "widget.widgetcell" ], "Ext.grid.column.Boolean": [ "widget.booleancolumn" ], "Ext.grid.column.Check": [ "widget.checkcolumn" ], "Ext.grid.column.Column": [ "widget.column", "widget.gridcolumn", "widget.templatecolumn" ], "Ext.grid.column.Date": [ "widget.datecolumn" ], "Ext.grid.column.Number": [ "widget.numbercolumn" ], "Ext.grid.column.RowNumberer": [ "widget.rownumberer" ], "Ext.grid.column.Selection": [ "widget.selectioncolumn" ], "Ext.grid.column.Text": [ "widget.textcolumn" ], "Ext.grid.column.Tree": [ "widget.treecolumn" ], "Ext.grid.menu.Columns": [ "widget.gridcolumnsmenu" ], "Ext.grid.menu.GroupByThis": [ "widget.gridgroupbythismenuitem" ], "Ext.grid.menu.ShowInGroups": [ "widget.gridshowingroupsmenuitem" ], "Ext.grid.menu.SortAsc": [ "widget.gridsortascmenuitem" ], "Ext.grid.menu.SortDesc": [ "widget.gridsortdescmenuitem" ], "Ext.grid.plugin.CellEditing": [ "plugin.cellediting", "plugin.gridcellediting" ], "Ext.grid.plugin.Clipboard": [ "plugin.clipboard" ], "Ext.grid.plugin.ColumnResizing": [ "plugin.columnresizing", "plugin.gridcolumnresizing" ], "Ext.grid.plugin.Editable": [ "plugin.grideditable" ], "Ext.grid.plugin.PagingToolbar": [ "plugin.gridpagingtoolbar", "plugin.pagingtoolbar" ], "Ext.grid.plugin.RowExpander": [ "plugin.rowexpander" ], "Ext.grid.plugin.RowOperations": [ "plugin.gridmultiselection", "plugin.multiselection", "plugin.rowoperations" ], "Ext.grid.plugin.Summary": [ "plugin.gridsummary", "plugin.gridsummaryrow", "plugin.summaryrow" ], "Ext.grid.plugin.ViewOptions": [ "plugin.gridviewoptions" ], "Ext.grid.plugin.ViewOptionsListItem": [ "widget.viewoptionslistitem" ], "Ext.grid.selection.Cells": [ "selection.cells" ], "Ext.grid.selection.Columns": [ "selection.columns" ], "Ext.grid.selection.Model": [ "selmodel.grid" ], "Ext.grid.selection.Replicator": [ "plugin.selectionreplicator" ], "Ext.grid.selection.SelectionExtender": [], "Ext.layout.Auto": [ "layout.auto", "layout.default" ], "Ext.layout.Box": [ "layout.box" ], "Ext.layout.Card": [ "layout.card" ], "Ext.layout.Carousel": [ "layout.carousel" ], "Ext.layout.Center": [ "layout.center" ], "Ext.layout.Fit": [ "layout.fit" ], "Ext.layout.Float": [ "layout.float" ], "Ext.layout.Form": [ "layout.form" ], "Ext.layout.HBox": [ "layout.hbox" ], "Ext.layout.VBox": [ "layout.vbox" ], "Ext.layout.card.fx.Abstract": [ "layout.card.fx.abstract" ], "Ext.layout.card.fx.Cover": [ "layout.card.fx.cover" ], "Ext.layout.card.fx.Cube": [ "layout.card.fx.cube" ], "Ext.layout.card.fx.Fade": [ "layout.card.fx.fade" ], "Ext.layout.card.fx.Flip": [ "layout.card.fx.flip" ], "Ext.layout.card.fx.Pop": [ "layout.card.fx.pop" ], "Ext.layout.card.fx.Reveal": [ "layout.card.fx.reveal" ], "Ext.layout.card.fx.Scroll": [ "layout.card.fx.scroll" ], "Ext.layout.card.fx.ScrollCover": [ "layout.card.fx.scrollcover" ], "Ext.layout.card.fx.ScrollReveal": [ "layout.card.fx.scrollreveal" ], "Ext.layout.card.fx.Serial": [], "Ext.layout.card.fx.Slide": [ "layout.card.fx.slide" ], "Ext.layout.card.fx.Style": [], "Ext.layout.overflow.Scroller": [ "layout.overflow.scroller" ], "Ext.layout.wrapper.BoxDock": [], "Ext.layout.wrapper.Inner": [], "Ext.list.AbstractTreeItem": [], "Ext.list.Location": [], "Ext.list.RootTreeItem": [], "Ext.list.Tree": [ "widget.treelist" ], "Ext.list.TreeItem": [ "widget.treelistitem" ], "Ext.menu.CheckItem": [ "widget.menucheckitem" ], "Ext.menu.Item": [ "widget.menuitem" ], "Ext.menu.Manager": [], "Ext.menu.Menu": [ "widget.menu" ], "Ext.menu.RadioItem": [ "widget.menuradioitem" ], "Ext.menu.Separator": [ "widget.menuseparator" ], "Ext.mixin.Accessible": [], "Ext.mixin.Bindable": [], "Ext.mixin.Bufferable": [], "Ext.mixin.ComponentDelegation": [], "Ext.mixin.ConfigProxy": [], "Ext.mixin.ConfigState": [], "Ext.mixin.Container": [], "Ext.mixin.Dirty": [], "Ext.mixin.Factoryable": [], "Ext.mixin.Focusable": [], "Ext.mixin.FocusableContainer": [], "Ext.mixin.Hookable": [], "Ext.mixin.Inheritable": [], "Ext.mixin.ItemRippler": [], "Ext.mixin.Keyboard": [], "Ext.mixin.Mashup": [], "Ext.mixin.Pluggable": [], "Ext.mixin.Progressable": [], "Ext.mixin.Queryable": [], "Ext.mixin.Responsive": [], "Ext.mixin.Selectable": [], "Ext.mixin.StoreWatcher": [], "Ext.mixin.StyleCacher": [], "Ext.mixin.Templatable": [], "Ext.mixin.Toolable": [], "Ext.mixin.Traversable": [], "Ext.navigation.Bar": [], "Ext.navigation.View": [ "widget.navigationview" ], "Ext.override.sparkline.Base": [], "Ext.overrides.Progress": [], "Ext.overrides.Widget": [], "Ext.overrides.app.Application": [], "Ext.overrides.dom.Element": [], "Ext.overrides.drag.proxy.Placeholder": [], "Ext.overrides.list.Tree": [], "Ext.overrides.list.TreeItem": [], "Ext.panel.Collapser": [], "Ext.panel.Collapsible": [], "Ext.panel.Date": [ "widget.datepanel" ], "Ext.panel.DateTitle": [ "widget.datetitle" ], "Ext.panel.DateView": [ "widget.dateview" ], "Ext.panel.Header": [ "widget.panelheader" ], "Ext.panel.Resizable": [], "Ext.panel.Resizer": [], "Ext.panel.Time": [ "widget.timepanel" ], "Ext.panel.TimeHeader": [ "widget.analogtimeheader" ], "Ext.panel.TimeView": [ "widget.analogtime" ], "Ext.panel.Title": [ "widget.paneltitle" ], "Ext.panel.YearPicker": [ "widget.yearpicker" ], "Ext.parse.Parser": [], "Ext.parse.Symbol": [], "Ext.parse.Tokenizer": [], "Ext.parse.symbol.Constant": [], "Ext.parse.symbol.Infix": [], "Ext.parse.symbol.InfixRight": [], "Ext.parse.symbol.Paren": [], "Ext.parse.symbol.Prefix": [], "Ext.perf.Accumulator": [], "Ext.perf.Monitor": [], "Ext.picker.Date": [ "widget.datepicker" ], "Ext.picker.Picker": [ "widget.picker" ], "Ext.picker.Slot": [ "widget.pickerslot" ], "Ext.picker.Tablet": [ "widget.tabletpicker" ], "Ext.plugin.Abstract": [], "Ext.plugin.AbstractClipboard": [], "Ext.plugin.MouseEnter": [ "plugin.mouseenter" ], "Ext.plugin.Responsive": [ "plugin.responsive" ], "Ext.plugin.TabGuard": [ "plugin.tabguard" ], "Ext.promise.Consequence": [], "Ext.promise.Deferred": [], "Ext.promise.Promise": [], "Ext.route.Action": [], "Ext.route.Handler": [], "Ext.route.Mixin": [], "Ext.route.Route": [], "Ext.route.Router": [], "Ext.scroll.Scroller": [ "scroller.scroller" ], "Ext.slider.Slider": [ "widget.slider" ], "Ext.slider.Thumb": [ "widget.thumb" ], "Ext.slider.Toggle": [ "widget.toggleslider" ], "Ext.sparkline.Bar": [ "widget.sparklinebar" ], "Ext.sparkline.BarBase": [], "Ext.sparkline.Base": [ "widget.sparkline" ], "Ext.sparkline.Box": [ "widget.sparklinebox" ], "Ext.sparkline.Bullet": [ "widget.sparklinebullet" ], "Ext.sparkline.CanvasBase": [], "Ext.sparkline.CanvasCanvas": [], "Ext.sparkline.Discrete": [ "widget.sparklinediscrete" ], "Ext.sparkline.Line": [ "widget.sparklineline" ], "Ext.sparkline.Pie": [ "widget.sparklinepie" ], "Ext.sparkline.RangeMap": [], "Ext.sparkline.Shape": [], "Ext.sparkline.TriState": [ "widget.sparklinetristate" ], "Ext.sparkline.VmlCanvas": [], "Ext.tab.Bar": [ "widget.tabbar" ], "Ext.tab.Panel": [ "widget.tabpanel" ], "Ext.tab.Tab": [ "widget.tab" ], "Ext.tip.Manager": [], "Ext.tip.ToolTip": [ "widget.tooltip" ], "Ext.util.AbstractMixedCollection": [], "Ext.util.Audio": [], "Ext.util.Bag": [], "Ext.util.Base64": [], "Ext.util.BufferedCollection": [], "Ext.util.CSS": [], "Ext.util.CSV": [], "Ext.util.ClickRepeater": [], "Ext.util.Collection": [], "Ext.util.CollectionKey": [], "Ext.util.Color": [], "Ext.util.Cookies": [], "Ext.util.DelimitedValue": [], "Ext.util.Draggable": [], "Ext.util.Filter": [], "Ext.util.FilterCollection": [], "Ext.util.Fly": [], "Ext.util.Format": [], "Ext.util.Geolocation": [], "Ext.util.Group": [], "Ext.util.GroupCollection": [], "Ext.util.Grouper": [], "Ext.util.HashMap": [], "Ext.util.History": [], "Ext.util.Inflector": [], "Ext.util.InputBlocker": [], "Ext.util.ItemCollection": [], "Ext.util.KeyMap": [], "Ext.util.KeyNav": [], "Ext.util.LineSegment": [], "Ext.util.LocalStorage": [], "Ext.util.LruCache": [], "Ext.util.MixedCollection": [], "Ext.util.ObjectTemplate": [], "Ext.util.Observable": [], "Ext.util.Offset": [], "Ext.util.PaintMonitor": [], "Ext.util.Point": [], "Ext.util.PositionMap": [], "Ext.util.Positionable": [], "Ext.util.Region": [], "Ext.util.Schedulable": [], "Ext.util.Scheduler": [], "Ext.util.SizeMonitor": [], "Ext.util.Sortable": [], "Ext.util.Sorter": [], "Ext.util.SorterCollection": [], "Ext.util.Spans": [], "Ext.util.TextMetrics": [], "Ext.util.TranslatableGroup": [], "Ext.util.TranslatableList": [], "Ext.util.TsvDecoder": [], "Ext.util.Wrapper": [], "Ext.util.XTemplateCompiler": [], "Ext.util.XTemplateParser": [], "Ext.util.paintmonitor.Abstract": [], "Ext.util.paintmonitor.CssAnimation": [], "Ext.util.paintmonitor.OverflowChange": [], "Ext.util.sizemonitor.Abstract": [], "Ext.util.sizemonitor.OverflowChange": [], "Ext.util.sizemonitor.Scroll": [], "Ext.util.translatable.Abstract": [], "Ext.util.translatable.Component": [ "translatable.component" ], "Ext.util.translatable.CssPosition": [ "translatable.cssposition" ], "Ext.util.translatable.CssTransform": [ "translatable.csstransform" ], "Ext.util.translatable.Dom": [ "translatable.dom" ], "Ext.util.translatable.ScrollParent": [ "translatable.scrollparent" ], "Ext.util.translatable.ScrollPosition": [ "translatable.scrollposition" ], "Ext.viewport.Android": [], "Ext.viewport.Default": [ "widget.viewport" ], "Ext.viewport.Ios": [], "Ext.viewport.Viewport": [], "Ext.viewport.WindowsPhone": [] });