/*
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 = '';
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] = '' + 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('', record[i], '>');
}
if (root) {
xml.push('', root, '>');
}
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, '', key, '>');
}
}
}
}
output.push('>');
output.push.apply(output, subOutput);
if (subObjects) {
for (key in subObjects) {
datum = subObjects[key];
this.objectToElement(key, datum, output);
}
}
output.push('', name, '>');
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('